Большое разложение класса в Java

Это не упоминается в документах, но можно переназначить атрибут AttributedString, просто добавив тот же атрибут:

AttributedString attributedString = new AttributedString("TEST TEXT");

attributedString.addAttribute(TextAttribute.BACKGROUND, Color.BLACK);//Initial assign
attributedString.addAttribute(TextAttribute.BACKGROUND, Color.GREEN);//Reassign
attributedString.addAttribute(TextAttribute.BACKGROUND, null);//Reset
11
задан starblue 23 February 2009 в 21:52
поделиться

5 ответов

Один способ начать разбивать такой большой объект состоит в том, чтобы сначала найти хорошее подмножество полей или свойств управляемым большим объектом, которые связаны друг с другом и которые не взаимодействуют с другими полями или свойствами объекта. Затем создайте новый, меньший объект с помощью только те поля. Таким образом, переместите всю логику от большого класса до нового меньшего класса. В исходном большом классе создайте метод делегации, который просто проводит запрос. Это - хороший первый шаг, который только включает изменение большого объекта. Это не сокращает количество методов, но это может значительно уменьшить сумму логики, необходимой в большом классе.

После нескольких раундов выполнения этого можно начать удалять часть делегации путем указания на другие объекты непосредственно на более новые, меньшие объекты, вместо того, чтобы проходить ранее огромный объект, который был посреди всего.

Посмотрите обсуждение шаблона Делегации Википедии, например.

Как простой пример, если Вы сделали, чтобы персонал возразил для представления штата в компании, затем Вы могли бы создать объект платежной ведомости отслеживать связанные с платежной ведомостью значения, объект оценок отслеживать оценки сотрудника, объект премий отслеживать премии, которые человек получил и так далее.

К остроумию, если Вы начали с одним большим классом, содержащим следующие методы, каждый содержащий бизнес-логику, среди многих других методов:

...
public boolean isManagement() { ... }
public boolean isExecutive() { ... }
public int getYearsOfService() { ... }
public Date getHireDate() { ... }
public int getDepartment() { ... }
public BigDecimal getBasePay() { ... }
public BigDecimal getStockShares() { ... }
public boolean hasStockSharePlan() { ... }
...

затем этот большой объект, в его конструкторе, мог создать недавно созданный объект StaffType и недавно созданный объект PayInformation и недавно созданный объект StaffInformation, и первоначально эти методы в большом объекте были бы похожи:

// Newly added variables, initialized in the constructor (or as appropriate)
private final StaffType      staffType;
private final StaffInformation staffInformation;
private final PayInformation payInformation;

...

public boolean isManagement() { return staffType.isManagement(); }
public boolean isExecutive() { return staffType.isExecutive(); }
public int getYearsOfService() { return staffInformation.getYearsOfService(); }
public Date getHireDate() { return staffInformation.getHireDate(); }
public int getDepartment() { return staffInformation.getDepartment(); }
public BigDecimal getBasePay() { return payInformation.getBasePay(); }
public BigDecimal getStockShares() { return payInformation.getStockShares(); }
public boolean hasStockSharePlan() { return payInformation.hasStockSharePlan(); }
...

куда вся логика, которая раньше была в большом объекте, была перемещена в эти три новых меньших объекта. С этим изменением можно повредить большой объект в меньшие части, не имея необходимость касаться чего-либо, что использует большой объект. Однако, поскольку Вы делаете это со временем, Вы найдете, что некоторым клиентам большого объекта, возможно, только понадобится доступ к одному из делимых компонентов. Для этих клиентов, вместо них использующий большой объект и делегирующий к конкретному объекту, они могут сделать прямое использование маленького объекта. Но даже если этот рефакторинг никогда не происходит, Вы улучшили вещи путем разделения бизнес-логики несвязанных объектов в различные классы.

15
ответ дан 3 December 2019 в 07:14
поделиться

Я видел некоторые случаи, где это решено наследованием: скажем, Большой класс заботится о 5 разных вещах, и (по различным причинам) они все должны быть в том же классе. Таким образом, Вы выбираете произвольный порядок наследования и определяете:

BigPart1 // all methods dealing with topic #1
BigPart2 extends BigPart1 // all methods dealing with topic #2
...
Big extends BigPart4 // all methods dealing with the last topic.

Если можно действительно разделить вещи на уровни, так, чтобы поломка имела смысл (Part2 на самом деле использует материал от Part1, но не наоборот, и т.д.), затем, возможно, это имеет некоторый смысл.

Место, где я видел это, находится в WebWorks, где единый класс имел тонны метода считывания/методов установщика - методы set, используемые для внедрения зависимости (например, URL args передал объекту после выполнения), и методы считывания для того, чтобы сделать значения доступными для различных шаблонов страницы (я думаю, что это был JSPs).

Так, разбивка сгруппировала материал логически, например, предположив, что класс назвали MyAction, был MyActionBasicArgs (поля и методы set для основных аргументов CGI), расширен MyActionAdvancedArgs (расширенная настройка args), расширенный MyActionExposedValues (методы считывания), расширенные MyActionDependencies (методы set, используемые внедрением зависимости Spring, не-CGI args), расширенный MyAction (который содержал фактическое, выполняют () метод).

Из-за пути внедрение зависимости в работах WebWorks (или по крайней мере, используемое для работы, тогда), это должен был быть один огромный класс, таким образом повредив его вниз этот путь, сделанный более удобными в сопровождении вещами. Но сначала, видят, можно ли просто постараться не иметь единственный огромный класс; думайте тщательно о своем дизайне.

1
ответ дан 3 December 2019 в 07:14
поделиться

Следующий логический шаг может быть должен изменить BigClass в пакет Java. Затем создайте новые объекты для каждой группы связанной функциональности (замечание в каждом классе, что объект является частью нового пакета).

Преимущества выполнения этого являются сокращением зависимости и производительностью.

  1. Никакая потребность импортировать весь package/BigClass только для получения нескольких методов.
  2. Изменения кода в связанной функциональности не требуют перекомпилировать/повторно развертывания всего package/BigClass.
  3. Меньше памяти использовало для выделения/освобождения объектов, так как Вы используете меньшие классы.
1
ответ дан 3 December 2019 в 07:14
поделиться

Да, C# обеспечивает частичные классы. Я предполагаю, что это - то, что Вы отсылаете к тому, когда Вы говорите:

C# решает такую проблему, позволяя повреждать реализацию класса в несколько исходных файлов: можно разделить объект бога любым путем, Вы выбираете, и он будет работать.

Это действительно помогает сделать огромные классы более управляемыми. Однако я нахожу частичные классы лучше всего используемыми, когда нужно расширить код, созданный генератором кода. Когда класс является столь большим, как Вы говорите о, он может почти всегда делиться на меньшие классы надлежащим объектно-ориентированным проектированием. Используя частичные шаги в сторону класса более правильный объект ориентировал дизайн, который иногда в порядке, поскольку конечная цель является стабильным, надежным, удобным в сопровождении кодом и не примером из учебника кода OO. Однако много раз помещение кода большого объекта в большое количество меньших частичных экземпляров класса того же класса не является идеальным решением.

Если можно возможно найти подмножества свойств объекта "бога", которые не взаимодействуют друг с другом, то каждый из тех наборов логически сделал бы хорошего кандидата на новый тип объекта. Однако, если все свойства этого объекта "бога" зависят друг от друга, то нет очень, можно сделать для разложения объекта.

0
ответ дан 3 December 2019 в 07:14
поделиться

Я не знаю, почему у Вас когда-либо был бы такой большой класс.

Я предполагаю, использовали ли Вы gui генерацию кода разработчика и были ленивый об этом, Вы могли бы закончить в такой ситуации, но codegen обычно заканчивается противный, если Вы не берете на себя управление сами.

Разделение единого класса произвольно является ужасным решением ужасной произведенной проблемы. (Повторное использование кода, с одной стороны, станет фактически невозможным),

Если необходимо использовать разработчика GUI, иметь его, создают меньшие компоненты, то используют маленькие компоненты для создания более крупного GUI. Каждый компонент должен сделать точно одно задание и сделать это хорошо.

Попытайтесь не КОГДА-ЛИБО отредактировать сгенерированный код, если можно избежать его. Помещение бизнес-логики в genned "кадр" является просто неприятным шаблоном разработки. Большинство генераторов кода не очень полезно с этим, так попытайтесь просто сделать единственное, минимальное редактирование для достигания то, в чем Вы нуждаетесь от внешних классов (думайте MVC, где кодом genned является Ваше Представление и код, Вы редактируете, должен быть в Вашей Модели и Контроллере).

Иногда можно просто выставить getComponents метод от объекта Кадра, вывести все компоненты путем итерации через контейнеры и затем динамично связать их с данными, и код (часто связывающий со свойством имени работает хорошо), я смог безопасно использовать редакторов формы этот путь, и весь обязательный код имеет тенденцию быть очень легко абстрагированным и снова использованным.

Если Вы не говорите о сгенерированном коде - Хорошо в Вашем классе "Бога", он делает точно одно небольшое задание и успевает он? В противном случае вытащите "Задание", поместите его в свой собственный класс и делегата в нем.

Ваш класс БОГА полностью учтен? Когда я видел огромные классы как это, я обычно видел много строк копии/вставки/редактирования. Если существует действительно подобие копии и мимо и отредактируйте некоторый раздел, то там достаточно для факторинга этих строк в единственный блок кода.

Если Ваш большой класс является классом GUI, считайте декораторов - допускающими повторное использование и материал перемещений из Вашего основного класса. Двойная победа.

Я предполагаю, что ответ на Ваш вопрос - то, что в Java мы просто используем хорошее OO, чтобы гарантировать, что проблема не возникает во-первых (или мы не делаем - Java, конечно, не неуязвимый для проблем, о которых Вы говорите больше, чем какой-либо другой язык),

0
ответ дан 3 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: