Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
/**
* 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). Последний раз я сдался и этот
ёжик теперь живет с нами.
StringCleanerFactory:
1. Массив symbolsToExclude всегда содержит одинаковые элементы, зачем его каждый раз пересоздавать?
2. Зачем synchronized? нет же обращения к глобальным мутабельным переменным...
Представленный код, возможно, не лишён некоторых недостатков. Но в целом концепция мне нравится, особенно если применять её для обработки строк, существующих в 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.: На мой взгляд, не стоит называть г-ном всё, чего не понимаешь.
Я искренне надеюсь что положительный рейтинг и восторженные комментарии побудят поклонников данного шедевра пересмотреть свои взгляды на прекрасное и отвратительное.
Ибо я боюсь что подобные "шедевры" ООП архитектуры (предоставляющие необъятный спектр предоставляемых возможностей) расплодятся и от количества гавна проект выйдет из под контроля и в один прекрасный момент рухнет как карточный домик.
P.S.
По моим догадкам САМ КОРОЛЬ АБСТРАКЦИЙ написал этот код под воздействием книги GOF Шаблоны Проектирования и применил здесь сразу: Фабрику, Стратегию, Комбинатор и благодаря этому они его восхваляют. Просто идеальное сочетание задачи и изящного архетиктурного решения.
Даже если это он :), то его аргументация не лишена смысла. Вот в ББ нет сплита. У меня тоже есть самоделка на эту тему.
Правда она не столь академически развесиста 🙂
Аргументация лишена смысла и вот почему:
Любой из этих клинеров можно заменить одним методом. Почему-то в библиотеке Java так и сделали. CombinedStringCleaner заменяется последовательным вызовом clean методов. Что получаем?
1) Не плодиться 100500 классов.
2) В коде, очищающем строку сразу понятно как именно очистилась строка. Там нет интерфейса StringCleaner, возвращенного абстрактной фабрикой, который не понятно что делает.
По аналогии со StringCleaner мне захотелось создать класс IntCalculator, который выполняет некоторую операцию на двумя int. Сделать подклассы IntAdd, IndSub, IntDiv, CombinedIntCalc и тд. Как тогда мы запишем 2 + 3 / 2 ?
Комбинированый обработчик строк все равно будет обернут методом с удобоваримым названием. Не вставлять же пятистрочную копипасту в каждом месте использования? Чтобы выяснить детали комбинации все-равно придется лазить в метод и смотреть. По размеру метод будет на пару-тройку строк короче чем представленное.
Работает представленное? Да и член с ним.
Насчет IntCalculator - все можно довести до абсурда. И к слову в жабе без автобоксинга (то самое ББ кстати) сложение Integer так и рассирается потому как там "+" так просто не напишешь для Integer, Long и т.д..
Удобно передать экземпляру EditField StringCleaner, который он будет применять в методе getText(). Иначе придётся применять метод очистки строк в сотне месте. При этом я не хочу, чтобы EditField знал о том, каким образом выполняется очистка строк (разным экземплярам я могу установить по-разному сформированные StringCleaner).
1) Десяток дополнительных классов в отдельном пакете меня не смущает: написал, отладил - и забыл про них.
2) Стараюсь придерживаться принципа минимизации мышления. На определённом уровне абстракции мне достаточно того, что строка очищается, в этот момент я не хочу задумываться о том, как именно это происходит.
Мойте строки перед едой исключительно с полиморфизьмом! Король абстракций и адепты абстрактного очищения строк в BlackBerry следят за вами. Мне кажется это заболевание называется StringClearner головного мозга.
я бы енум из некоторых трансформеров сделал, есть проблемы с компиляцией в java 1.5 (методы интерфейсов нельзя было оверрайдить), в остальном - круто а ещё StringTransformer можно было бы заменить на Function<String, String>, особенно, если используется Google Guava
Да в общем-то почти всегда можно обойтись стандартными StringBuilder/Buffer.
A StrBuilder - это их альтернатива. Выше по треду речь шла о резаных нативных классах.
class Example - ессно велосипед, но собран он хорошо.
> Я удалял этот StringCleaner API 3 раза, и каждый раз наши адепты стринг клинеров под любым предлогом поднимали это г***о из анналов ада (svn history).
Я так понимаю, просто вы не в состоянии довести мозг до такой степени аноксической асфиксии, чтобы получить ТАКИЕ строки которыми пользовались ваши Адепты
Мне одному кажется, что для этого как раз и были придуманы регулярные выражения? - ну найти там какие-то симвлы в строке, или заменить... да и универсально вроде. Или я снова в Java что-то очень важное упустил?
Оверинжениринг во всей красе...
1. Массив symbolsToExclude всегда содержит одинаковые элементы, зачем его каждый раз пересоздавать?
2. Зачем synchronized? нет же обращения к глобальным мутабельным переменным...
2. а вдруг авторы захотят распаралелить чистку строк? строки чистить это вам не шнурки гладить!
И вообще, я за чистый код.
Каждый класс должен быть вычищен.
Автор темы утверждает, что очистить строку от мусора можно применением пары методов класса 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();
> String, существующий в BlackBerry
Гуест, ты бухой чтоли? Не подскажешь, а в винде какие стринги существуют?
The truth is that there is no spoon string.
P.S.
Гавно или не гавно решат зрители. +1 за гавно. ведь это гавнокод правильно?
ораторег в треде
Ибо я боюсь что подобные "шедевры" ООП архитектуры (предоставляющие необъятный спектр предоставляемых возможностей) расплодятся и от количества гавна проект выйдет из под контроля и в один прекрасный момент рухнет как карточный домик.
P.S.
По моим догадкам САМ КОРОЛЬ АБСТРАКЦИЙ написал этот код под воздействием книги GOF Шаблоны Проектирования и применил здесь сразу: Фабрику, Стратегию, Комбинатор и благодаря этому они его восхваляют. Просто идеальное сочетание задачи и изящного архетиктурного решения.
Простите, наболело.
Так комментарии для этого и созданы.
http://www.phppatterns.com/docs/design/hello_world_in_patterns
Правда она не столь академически развесиста 🙂
Любой из этих клинеров можно заменить одним методом. Почему-то в библиотеке Java так и сделали. CombinedStringCleaner заменяется последовательным вызовом clean методов. Что получаем?
1) Не плодиться 100500 классов.
2) В коде, очищающем строку сразу понятно как именно очистилась строка. Там нет интерфейса StringCleaner, возвращенного абстрактной фабрикой, который не понятно что делает.
По аналогии со StringCleaner мне захотелось создать класс IntCalculator, который выполняет некоторую операцию на двумя int. Сделать подклассы IntAdd, IndSub, IntDiv, CombinedIntCalc и тд. Как тогда мы запишем 2 + 3 / 2 ?
Нет. Ну Вы подумайте о
>необъятном спектре предоставляемых возможностей.
/r Тараса
Но в целом полностью согласен.
Работает представленное? Да и член с ним.
Насчет IntCalculator - все можно довести до абсурда. И к слову в жабе без автобоксинга (то самое ББ кстати) сложение Integer так и рассирается потому как там "+" так просто не напишешь для Integer, Long и т.д..
dixi
1) Десяток дополнительных классов в отдельном пакете меня не смущает: написал, отладил - и забыл про них.
2) Стараюсь придерживаться принципа минимизации мышления. На определённом уровне абстракции мне достаточно того, что строка очищается, в этот момент я не хочу задумываться о том, как именно это происходит.
наверное
Простите за форматирование, делал покороче =)
а ещё StringTransformer можно было бы заменить на Function<String, String>, особенно, если используется Google Guava
И не писал бы свои велосипеды.
К тому же там есть этот ваш флюент-интерфейс.
A StrBuilder - это их альтернатива. Выше по треду речь шла о резаных нативных классах.
class Example - ессно велосипед, но собран он хорошо.
Осталось только реализовать normalizeWhitespaces. Правда normalizeWhitespaces нужен не так уж часто.
Слава велосипедам!
Я так понимаю, просто вы не в состоянии довести мозг до такой степени аноксической асфиксии, чтобы получить ТАКИЕ строки которыми пользовались ваши Адепты
Но зачем? Это работает через конвеер: