Нужен совет по философии ООП - PullRequest
3 голосов
/ 19 мая 2010

Я пытаюсь заставить колеса крутиться на большом проекте в C #. Мой предыдущий опыт был в Delphi, где по умолчанию каждая форма создавалась при запуске приложения, и ссылки на формы содержались в (задыхающихся) глобальных переменных. Поэтому я пытаюсь приспособить свое мышление к 100% объектно-ориентированной среде, и моя голова немного кружится.

В моем приложении будет большая коллекция классов. Большинству этих классов нужен только один экземпляр. Вот я и подумал: статические классы. Я не совсем уверен, почему, но многое из того, что я здесь прочитал, говорит о том, что если мой класс будет содержать состояние, которое, как я понимаю, означает любые значения свойств, я должен вместо этого использовать одноэлементную структуру. Хорошо. Но есть люди, которые по причинам, которые избегают меня, думают, что синглтоны тоже злые.

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

Тогда возникает проблема взаимодействия между объектами. Я испытываю желание создать класс Global, полный общедоступных статических свойств, ссылающихся на отдельные экземпляры многих из этих классов. Я также подумал о том, чтобы просто сделать их свойства (статические или экземпляры, не уверен, какие) из MainForm. Тогда я бы хотел, чтобы каждый из моих классов знал о MainForm как о Владельце. Тогда различные объекты могут ссылаться друг на друга как Владелец. Объект1 , Владелец. Объект2 и т. Д.

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

Заранее спасибо, Дэвид Дженнингс

Ответы [ 6 ]

4 голосов
/ 19 мая 2010

Очень нормально переходить от процедурных или других не-ООП языков и думать «Один гигантский статический класс на XYZ», и это обычно означает, что вы на самом деле не думали об ОБЪЕКТАХ, которые представлены, потому что класс должен представлять ОБЪЕКТЫ, которыми нужно манипулировать.

Итак, вам нужно отступить назад и посмотреть на ДАННЫЕ и на то, что ДАННЫЕ представляют. Вы можете сказать: «Ну, это ДАННЫЕ! Они представляют НОМЕРА!», Но вы должны абстрагироваться от представления данных. «Предмет», который представляют данные, - это Объект. Действия, которые вы выполняете над данными, которые представляет «вещь», становятся вашими методами.

2 голосов
/ 19 мая 2010

Статические классы и синглтоны имеют одинаковые недостатки:

  • Плотно связан со многими другими классами
  • Скрыть зависимости (сложно сказать, какие классы их используют)
  • Трудности при тестировании
  • По существу глобальные данные
  • Для синглетонов - множественные обязанности (что бы они ни делали + управление жизненным циклом)

Решением во многих (не во всех!) Случаях является Внедрение зависимостей (DI), основанное на Принципе обращения зависимостей (один из принципов SOLID упомянутый @CodeToGlory). Это можно сделать вручную или с помощью DI-контейнера Framework .

У Марка Симанна есть отличная книга по Внедрение зависимостей в .NET ; Я настоятельно рекомендую это.

2 голосов
/ 19 мая 2010

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

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

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

1 голос
/ 19 мая 2010

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

Я чувствую, что было бы хорошо получить учебник по ТВЕРДЫМ Принципам. На эту тему также есть несколько dimecasts, которые вы должны посмотреть и понять.

Еще одна практическая книга, которую я бы порекомендовал, - "Реализация шаблонов" Кента Бека. Понимание ООП - это одно, а реализация в реальном мире - совсем другое.

Взгляните на Windows Presentation Foundation, систему презентаций следующего поколения для создания клиентских приложений Windows.

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

0 голосов
/ 19 мая 2010

При чтении вашего объяснения часть меня думает, что вы, возможно, все еще думаете в парадигме Delphi, если у вас есть столько классов, которые вы считаете статичными или одиночными. Я не знаю, сталкивался ли я когда-либо с проектом, где был только один из большинства объектов. Так что я склоняюсь к тому, что ваша декомпозиция объекта может быть ошибочной.

На самом деле вы должны начать думать о том, что вы представляете в своей программе. Спросите себя, если у вас много объектов, у которых есть только один экземпляр, почему только один экземпляр? Это потому, что вы храните данные странным образом, например, с несколькими массивами, индексы которых совпадают.

То, что в C # действительно есть хорошая встроенная семантика для синглетонов, в которой вам не нужно выполнять проверку нуля в вашем методе экземпляра

public class SingletonClass{
     private static SingletonClass _instance;

     private SingletonClass(){}

     public static Instance
     {
         get
         {
             if(_instance == null){
                _instance = new SingletonClass();
             }
         }
     }

}

В C # можно записать как:

public class SingletonClass{
     private static SingletonClass _instance = new SingletonClass();

     private SingletonClass(){}

     public static Instance
     {
         get
         {
            return _instance;
         }
     }

}

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

Я бы настоятельно рекомендовал вам подумать о том, почему у вас глобальное состояние со статическими методами или синглетонами.

0 голосов
/ 19 мая 2010

Несколько случайных мыслей по этому поводу, которые могут или не могут быть полезны:

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

  • Мой опыт показывает, что с процедурным кодом вы думаете: «Что я делаю сейчас?» но с ОО-кодом вы думаете: «Что я мог бы когда-нибудь сделать?»

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

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

Что касается всего Синглтона - и, не желая быть провокационным, - игнорируйте скептиков. Бывают случаи, когда шаблон проектирования Singleton фантастически полезен, как и времена, когда модель данных EAV идеальна, а MVC - худшая вещь в мире. Если вам нужно вставить винт, используйте отвертку.

...