1. Java / Говнокод #8260

    +94

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    /**
     * Interface for string cleaners. Defines method that takes a string to perform cleaning and returns
     * cleaned string.
     * 
     * @author Король Абстракций.
     * @version 1.0 29.04.2011
     *
     */
    public interface StringCleaner {
    	//---------------------------------------------------------------------------------------------
    	/**
    	 * Cleans given string. Returns cleaned string.
    	 * @param string String to clean
    	 * @return Cleaned string
    	 * @throws NullPointerException <code>If string == null</code>
    	 * @since 1.0
    	 */
    	public String clean(String string);
    	//---------------------------------------------------------------------------------------------
    }
    
    // Далее реализации.
    
    public abstract class SymbolStringCleaner implements StringCleaner { ... }
    public final class AllSymbolStringCleaner extends SymbolStringCleaner { ... }
    public final class RepeatedSymbolStringCleaner extends SymbolStringCleaner { ... }
    public class TrimStringCleaner extends SymbolStringCleaner { ... }
    public final class CombinedStringCleaner implements StringCleaner { ... }
    
    // Пример использования.
    
    public class StringCleanerFactory {
    	private static final char END_OF_LINE_SYMBOL = '\n';
    	
    	public static synchronized StringCleaner createCommonStringCleaner() {
    		char[] symbolsToExclude = new char[] {' ', END_OF_LINE_SYMBOL};
    		StringCleaner repeatedSymbolsCleaner = new RepeatedSymbolStringCleaner(symbolsToExclude);
    		StringCleaner trimCleaner = new TrimStringCleaner(symbolsToExclude, true, true);
    		
    		CombinedStringCleaner resultCleaner = new CombinedStringCleaner();
    		resultCleaner.add(repeatedSymbolsCleaner);
    		resultCleaner.add(trimCleaner);
    		return resultCleaner;
    	}
    }
    
    // В реале выходит что-то вроде
    
    return str.trim().replace(" \n", '');

    Очистка строк огнем инквизиции еше никогда не была настолько абстрактной.


    P.S.

    Я удалял этот StringCleaner API 3 раза, и каждый раз наши адепты стринг клинеров под любым
    предлогом поднимали это г***о из анналов ада (svn history). Последний раз я сдался и этот
    ёжик теперь живет с нами.

    Запостил: enikey, 21 Октября 2011

    Комментарии (61) RSS

    • А можно полные исходники этих классов? Я хочу заюзать их в своем проекте
      Ответить
      • напомнило медиков, которые заражали себя для проведения исследований
        Ответить
    • Строки должны быть тщательно помыты и высушены
      Оверинжениринг во всей красе...
      Ответить
      • Вспоминаю Тараса и его выражение "ООПизм головного мозга"
        Ответить
    • StringCleanerFactory:
      1. Массив symbolsToExclude всегда содержит одинаковые элементы, зачем его каждый раз пересоздавать?
      2. Зачем synchronized? нет же обращения к глобальным мутабельным переменным...
      Ответить
      • 1. какой вы негигиеничный человек! предыдущая версия может была уже сильно испачкана!! надо еще добавить StringCleanerCleaner - и все будет в ажуре.

        2. а вдруг авторы захотят распаралелить чистку строк? строки чистить это вам не шнурки гладить!
        Ответить
        • Да ну? А если StringCleanerCleaner будет испачкан? На помощь придет StringCleanerCleanerCleaner!

          И вообще, я за чистый код.
          Каждый класс должен быть вычищен.
          Ответить
    • А если потратить на разработку стринг клинеров 3 человека-месяца, то они будут стоит как пылесос кирби, но будут чистить намного лучше
      Ответить
    • HolyStringCleaner очистит ваши строки от ереси
      Ответить
    • Представленный код, возможно, не лишён некоторых недостатков. Но в целом концепция мне нравится, особенно если применять её для обработки строк, существующих в Blackberry. Эти строки значительно урезаны. Специально не проверял, но часто базовые классы в Blackberry JRE урезаны даже по сравнению с J2ME.
      Автор темы утверждает, что очистить строку от мусора можно применением пары методов класса String. Но это не всегда так.
      Пример1. Дана строка " \n \n some\n string \n". На выходе мы хотим получить строку "some\nstring" (то есть убрать незначащие символы по краям и оставить по одному разделителю между словами). trim() даст нам только "\n \n some\n string \n". Далее, в String, существующем в BlackBerry, есть только один метод replace:
      public String replace(char oldChar, char newChar)
      Если честно, я не понимаю, как с помощью этого метода можно получить "some\nstring" из "\n \n some\n string \n" (как предлагает нам автор темы).
      Пример 2. Ещё проще, дана строка "some string". Стандартным методом BlackBerry String получить из этой строки "some string" невозможно, придётся писать хоть и простой, но алгоритм. А StringCleaner сделает это легко.
      Применение комбинированного StringCleaner делает концепцию гибкой и расширяемой.
      Таким образом, автор темы не сумел оценить концепцию StringCleaner и объять спектр предоставляемых возможностей.
      P. S.: На мой взгляд, не стоит называть г-ном всё, чего не понимаешь.
      Ответить
      • Вот вам еще один гк:
        while(SomeString.contains(" ")) //два пробела
        a = a.replaceAll(" ", " "); //заменяем два пробела на один
        return a.trim();
        Ответить
      • Король Абстракций, залогинься.
        Ответить
      • > строк, существующих в Blackberry
        > String, существующий в BlackBerry

        Гуест, ты бухой чтоли? Не подскажешь, а в винде какие стринги существуют?
        Ответить
      • return MyСуперStringUtilities.replace(src.trim( ), " \n", "") не?

        P.S.

        Гавно или не гавно решат зрители. +1 за гавно. ведь это гавнокод правильно?
        Ответить
        • >+1 за гавно. ведь это гавнокод правильно?
          ораторег в треде
          Ответить
          • Я искренне надеюсь что положительный рейтинг и восторженные комментарии побудят поклонников данного шедевра пересмотреть свои взгляды на прекрасное и отвратительное.

            Ибо я боюсь что подобные "шедевры" ООП архитектуры (предоставляющие необъятный спектр предоставляемых возможностей) расплодятся и от количества гавна проект выйдет из под контроля и в один прекрасный момент рухнет как карточный домик.

            P.S.

            По моим догадкам САМ КОРОЛЬ АБСТРАКЦИЙ написал этот код под воздействием книги GOF Шаблоны Проектирования и применил здесь сразу: Фабрику, Стратегию, Комбинатор и благодаря этому они его восхваляют. Просто идеальное сочетание задачи и изящного архетиктурного решения.

            Простите, наболело.
            Ответить
            • >Простите, наболело.
              Так комментарии для этого и созданы.

              http://www.phppatterns.com/docs/design/hello_world_in_patterns
              Ответить
    • Причем тут Blackberry? Король Абстракций, это ты?
      Ответить
      • Даже если это он :), то его аргументация не лишена смысла. Вот в ББ нет сплита. У меня тоже есть самоделка на эту тему.
        Правда она не столь академически развесиста :)
        Ответить
        • AbstractStringSplitter?
          Ответить
        • Аргументация лишена смысла и вот почему:
          Любой из этих клинеров можно заменить одним методом. Почему-то в библиотеке Java так и сделали. CombinedStringCleaner заменяется последовательным вызовом clean методов. Что получаем?
          1) Не плодиться 100500 классов.
          2) В коде, очищающем строку сразу понятно как именно очистилась строка. Там нет интерфейса StringCleaner, возвращенного абстрактной фабрикой, который не понятно что делает.

          По аналогии со StringCleaner мне захотелось создать класс IntCalculator, который выполняет некоторую операцию на двумя int. Сделать подклассы IntAdd, IndSub, IntDiv, CombinedIntCalc и тд. Как тогда мы запишем 2 + 3 / 2 ?
          Ответить
          • Но это же ГИБКАЯ и РАСШИРЯЕМАЯ КОНЦЕПЦИЯ!
            Нет. Ну Вы подумайте о
            >необъятном спектре предоставляемых возможностей.
            /r Тараса
            Ответить
            • необъятном спектре никому не нужных предоставляемых возможностей
              Ответить
          • Придумал пример когда классы и CombinedStringCleaner обоснованы =)

            Но в целом полностью согласен.
            Ответить
          • Комбинированый обработчик строк все равно будет обернут методом с удобоваримым названием. Не вставлять же пятистрочную копипасту в каждом месте использования? Чтобы выяснить детали комбинации все-равно придется лазить в метод и смотреть. По размеру метод будет на пару-тройку строк короче чем представленное.
            Работает представленное? Да и член с ним.

            Насчет IntCalculator - все можно довести до абсурда. И к слову в жабе без автобоксинга (то самое ББ кстати) сложение Integer так и рассирается потому как там "+" так просто не напишешь для Integer, Long и т.д..

            dixi
            Ответить
            • Имхо StringCleaner'ы уже доведены до абсурда сами по себе.
              Ответить
          • Удобно передать экземпляру EditField StringCleaner, который он будет применять в методе getText(). Иначе придётся применять метод очистки строк в сотне месте. При этом я не хочу, чтобы EditField знал о том, каким образом выполняется очистка строк (разным экземплярам я могу установить по-разному сформированные StringCleaner).
            1) Десяток дополнительных классов в отдельном пакете меня не смущает: написал, отладил - и забыл про них.
            2) Стараюсь придерживаться принципа минимизации мышления. На определённом уровне абстракции мне достаточно того, что строка очищается, в этот момент я не хочу задумываться о том, как именно это происходит.
            Ответить
        • Действительно. Отчего бы и нет.
          Ответить
      • Это адепт. Сам король в стороне.
        Ответить
    • Мойте строки перед едой исключительно с полиморфизьмом! Король абстракций и адепты абстрактного очищения строк в BlackBerry следят за вами. Мне кажется это заболевание называется StringClearner головного мозга.
      Ответить
    • А мне нравиться этот код, я сумасшедший?
      Ответить
    • import java.util.ArrayList;
      import java.util.List;
      
      public class Example {
      
      	public static interface StringTransform { String transform(String string); }
      	
      	public static final StringTransform TRIM = new StringTransform() { @Override public String transform(String string) { 
      			return string.trim(); }};
      	
      	public static final StringTransform NORMALIZE_WHITESPACES = new StringTransform() { @Override public String transform(String string) { 
      			return string.replaceAll("\\s{2,}", " "); }};
      
      	public static final StringTransform UPCASE = new StringTransform() { @Override public String transform(String string) { 
      		return string.toUpperCase(); }};
      				
      	public static class StringTransformer implements StringTransform {
      		private List<StringTransform> transforms = new ArrayList<StringTransform>();
      		
      		@Override public String transform(String string) { 
      			for (StringTransform cleaner : transforms) { 
      				string = cleaner.transform((string)); 
      			} return string; }
      		
      		public StringTransformer trim() { transforms.add(TRIM); return this; }
      		public StringTransformer normalizeWhitespaces() { transforms.add(NORMALIZE_WHITESPACES); return this; }
      		public StringTransformer upcase() { transforms.add(UPCASE); return this; }
      		
      		public StringTransformer replace(final char oldChar, final char newChar) { 
      			transforms.add(new StringTransform() {
      				@Override public String transform(String string) {
      					return string.replace(oldChar, newChar);
      				}
      			}); 
      			return this; 
      		}
      	}
      	
      	public static void main(String[] args) {
      		String result = new StringTransformer()
      			.trim()
      			.normalizeWhitespaces()
      			.upcase()
      			.replace('!', '?')
      			.transform("  Hello  World!   ");
      		System.out.println(result);
      	}
      	
      }


      Простите за форматирование, делал покороче =)
      Ответить
      • я бы енум из некоторых трансформеров сделал, есть проблемы с компиляцией в java 1.5 (методы интерфейсов нельзя было оверрайдить), в остальном - круто
        а ещё StringTransformer можно было бы заменить на Function<String, String>, особенно, если используется Google Guava
        Ответить
        • А я бы использовал StrBuilder в комбинации с StrMatcherом, которые в Apache Commons Lang.
          И не писал бы свои велосипеды.

          К тому же там есть этот ваш флюент-интерфейс.
          Ответить
          • Я бы вообще ничего не подключал без надобности. В большинстве проектов, функциональности больше чем isBlank и join не требуется.
            Ответить
            • Да в общем-то почти всегда можно обойтись стандартными StringBuilder/Buffer.
              A StrBuilder - это их альтернатива. Выше по треду речь шла о резаных нативных классах.

              class Example - ессно велосипед, но собран он хорошо.
              Ответить
      • String result = " Hello World! ".trim().toUpperCase().replace('!', '?');

        Осталось только реализовать normalizeWhitespaces. Правда normalizeWhitespaces нужен не так уж часто.
        Слава велосипедам!
        Ответить
        • Этот вилосипед был написан от нефиг делать для прикола =)
          Ответить
    • показать все, что скрытоЯ хороший троль, сытый. Ы)
      Ответить
    • > Я удалял этот StringCleaner API 3 раза, и каждый раз наши адепты стринг клинеров под любым предлогом поднимали это г***о из анналов ада (svn history).
      Я так понимаю, просто вы не в состоянии довести мозг до такой степени аноксической асфиксии, чтобы получить ТАКИЕ строки которыми пользовались ваши Адепты
      Ответить
      • Не асфиксии, а просветления. И да, Адепт, кончай прятатся под маской анонимуса - логинься!
        Ответить
      • семь раз надо удалять, тогда сбудется
        Ответить
    • Мне одному кажется, что для этого как раз и были придуманы регулярные выражения? - ну найти там какие-то симвлы в строке, или заменить... да и универсально вроде. Или я снова в Java что-то очень важное упустил?
      Ответить
      • Регулярки - это чёрная магия, а стринг клинер - это модно и универсально!
        Ответить
        • Напрашивается RegexpStringCleaner
          Ответить
          • Уйди, демон! Регулярки могут быть внутри, как предложили выше.
            Ответить
            • Ведь СтрингКлинер это абстракция высшего порядка! Все уже начали делать порты этой библиотеки для очистки строк на другие языки?
              Ответить
              • >на другие языки

                Но зачем? Это работает через конвеер:
                cat dirty_file | stringcleaner -trim > clean_file
                Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий