2015-02-02 2 views
4

Я пишу основополагающие классы для приложения и хочу правильно их построить для долговременной ремонтопригодности. С этой целью я исследую, какие шаблоны проектирования реализовать, использовать интерфейсы, абстрактные классы и отделить упорство от активности. Моя голова плавает с узорами, парадигмами и принципами.Должен ли я разделять свойства и методы в частичных классах?

У меня есть класс Product, для которого я создал интерфейс IProduct. Я считаю, что мне нужно сделать Product и абстрактный класс, потому что любой экземпляр его должен быть одним из полдюжины значений для свойства Category. Итак, мой первый вопрос: следующий способ сделать это?

abstract class Product : IProduct 
{ 
    // Fields 
    // Properties 
    // Methods 
} 

interface IProduct 
{ 
    // Properties 
} 

public class Model : IProduct 
{ 
    public Model() 
    { 
     Category = "Model"; 
    } 

    // Model-specific fields 
    // Model-specific properties 
    // Model-specific methods 
} 

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

abstract class Product : IProduct 
{ 
    // Fields 
    // Properties 
    // Methods 
} 

interface IProduct 
{ 
    // Properties 
} 

public partial class Model : IProduct 
{ 
    public Model() 
    { 
     Category = "Model"; 
    } 

    // Model-specific fields 
    // Model-specific properties 
} 

public partial class Model : IProduct 
{ 
    // Model-specific methods 
} 

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

И, наконец, если разделение свойств и методов является хорошей вещью, а Product имеет некоторые методы, применимые ко всем конкретным версиям, следует ли перенести их в отдельный абстрактный класс?

abstract class Product : IProduct 
{ 
    // Fields 
    // Properties 
} 
abstract class Product : IProduct 
{ 
    // Methods 
} 
+16

Я лично никогда не чувствовал необходимости создавать несколько частичных классов для разделения свойств и методов. Я не понимаю. Вы могли бы пойти еще дальше и начать разделять открытый интерфейс с частным в еще более частичных классах. Я думаю, что это не делает ничего, кроме того, что код * сложнее поддерживать, добавляя кучу бесполезных когнитивных накладных расходов. Получайте удовольствие, прыгая между файлами/много строк, чтобы понять поток данной функции. Просто держите вещи разделенными в определении класса логически и должны быть последовательными. –

+1

"* persistence and activity *" - Я думаю, что это «java-way» обработки: наличие сущностей (* немых данных-структур *) и сервисов (* работа с сущностями *). В C# я никогда их не разделял - и в конце это просто личное предпочтение, если вы хотите называть 'user.Save()' или 'userService.Save (user);' – dognose

+0

Все зависит от того, что вам нужно. Является ли оно ориентированным на приложение на основе пользовательского интерфейса или «основополагающим», вы имеете в виду базовую структуру кода? –

ответ

5

Единственное использование я вижу в соответствии partial классов, когда две отдельных систем обновления двух файлов. Это справедливо, например, при использовании дизайнеров Visual Studio (например, дизайнер Windows Forms), которые обновляют свой собственный файл класса. Другое дело может быть правдой для другого автоматически генерируемого вами класса. Одна из них поддерживается системой, одна из вас.

Я никогда не испытывал желания иметь два отдельных файла класса partial, которые я поддерживаю. Обычно я использую директивы #region для разделения методов и свойств.

+1

Следует избегать использования '# region': http://programmers.stackexchange.com/a/53114/14244 –

+4

@WillMarcouiller Я согласен с использованием регионов внутри методов, но в классах я не знаю, Не вижу проблемы. –

+0

Насколько хорошо вы находите, что работает в среде, где несколько разработчиков работают над одним и тем же кодом? Исторически, когда я писал код (который редко), я был единственным разработчиком. В этой ситуации я разделяю пространство с фактическим профессиональным разработчиком, со мной выступает в качестве аналитика и архитектор программного обеспечения. Мы уже сталкиваемся друг с другом, когда он работает над битами сохранения (EF), когда я работаю над бизнес-слоем. –

1

Лично я предпочитаю комбинировать семантический подход и подход, основанный на видимости, для сортировки членов внутри класса. На самом деле я не знаю, кто когда-либо «изобрел» правило для сортировки членов на основе типа языковой сущности (т. Е. Полей в группе, свойств в группе и т. Д.). Это почти не имеет смысла в отношении удобочитаемости.

Полезно использовать директивы #region для их разделения. Кроме того, я предпочитаю использовать горизонтальные линии (------…---), чтобы сделать код более читаемым.

Пример:

public class SomeClass : ParentClass, ISomeInterface 
{ 
    #region ------ Large feature 1 ---------------------------- 
    … // any non-private members related to 'Large feature 1' go here 
    #endregion 

    #region ------ Large feature 2 ---------------------------- 
    … // any non-private members related to 'Large feature 2' go here 
    #endregion 

    #region ------ Implementation of ISomeInterface ----------- 
    … // ISomeInterface implementation goes here, comments are *not* repeated 
    #endregion 

    #region ------ ParentClass overrides ---------------------- 
    … // parent class members' overrides go here, comments are *not* repeated 
    #endregion 

    #region ------ Internals ---------------------------------- 
    … // any private members, i.e. the actual implementation 
    #endregion 
} 

Там нет причин чрезмерной использовать частичные декларации, если вы действительно не должны иметь их в отдельных файлах. Хорошая причина в том, что часть класса автогенерируется. Однако использование частичных деклараций исключительно для разделения членов гораздо менее читаемо и сопровождается, чем последовательное использование регионов.

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

public int SomeProperty 
{ 
    get { … return someProperty; } 
    set { someProperty = value; … } 
} 
private int someProperty; 
+1

Было бы намного проще и сделать ваш код более чистым, если вы поместите эти «большие функции» в собственный класс, следуя за SRP: http://en.wikipedia.org/wiki/Single_responsibility_principle –

+0

@WillMarcouiller Честно говоря, это было бы безусловно, будет хорошей идеей признать, что разработка программного обеспечения - это широкая область, решающая широкий круг проблем, где один размер ** не подходит для всех. Я не плачу разработчикам за то, чтобы перерабатывать вещи, но для создания рабочего, чистого, адекватно сложного кода, не препятствуя тому, чтобы младшие/менее квалифицированные разработчики/новые дети на blcok присоединялись к команде без сильной боли (и затрат) :-) –

+0

@WillMarcouiller Не стесняйтесь принимать 'SomeClass' =' Customer', 'Large feature 1' = 'Идентификационные данные, такие как имя, фамилия, Nick', 'Large feature 2' = 'Контакты, такие как адрес, адрес электронной почты, IM-имя или независимо от того, что явно не противоречит СРП. –

Смежные вопросы