На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! В разделе обсуждаются следующие темы:
1) Процесс разработки программного обеспечения.
2) Определение требований к программному обеспечению.
3) Составные части и процесс проектирования (см. Шаблоны проектирования).
4) Документирование программного продукта(проекта).
5) Руководство разработкой программного обеспечения.
6) Проектирование пользовательского интерфейса.
7) Контроль версий проекта (см. Управление версиями в Subversion, Стратегии использования svn).
Модераторы: ElcnU
  
> Как гулять с собакой согласно ООП?
    Обнаружил интересную статью http://habrahabr.ru/post/147927/
    Там есть пример с классом собаки. В классе собаки (или вне его) должен быть метод "выгулять". Дополнительно будем задавать сколько часов гулять.

    Есть несколько решений
    1. Решение в стиле С - вообще не ООП
    ExpandedWrap disabled
      class Dog
      {
         //данные класса "собака"
      };
      void walk(Dog& dog, int h){
      //...
      }
      Dog dog;
      walk(dog, 1);


    2. Метод класса с параметром
    ExpandedWrap disabled
      class Dog
      {
         //данные класса "собака"
         public:
         void walk(int h);//метод "выгулять собаку в течение h часов"
      };
      Dog dog;
      dog.walk(1);


    3. Метод класса без параметра, который в данных класса

    ExpandedWrap disabled
      class Dog
      {
         //данные класса "собака"
         public:
         void walk();//метод "выгулять собаку"
         void set_hours(int h)//сколько часов будем гулять?
      };
      Dog dog;
      set_hours(1);
      dog.walk();


    4. Создать "менеджер собак", в котором будет метод выгуливания. Но здесь тоже есть вопросы. Должен ли он содержать в себе объект собаки (или все объекты собак в программе), или может быть он должен наследоваться от класса собаки? Или может быть собака наследуется от своего менеджера?

    ExpandedWrap disabled
      class DogManager1
      {
      public:
         void walk(Dog& dog, int h);
      };
      class DogManager2
      {
      Dog dog;
      public:
         void walk(int h);
      };
      class DogManager3
      {
      vector<Dog> dogs;
      public:
         void walk(int h, int n_dog);
      };
      //и еще много вариантов


    Какое решение вы считаете лучшее?
      Первый или второй как наиболее простые. Выбор из них будет зависеть от языка.
      Третий вариант — это, по-моему, пример плохого дизайна: ну зачем в классе собаки хранить параметр часов текущего выгула, если это не ее характеристика?
      Четвертый — какой-то «over-engineering», необоснованно (пере)усложнен, попахивает «паттернами проектирования головного мозга».
        seregaz, фишка в том, что операция "выгул собаки" - это не ответственность собаки. :) Хоть в прямом, хоть в переносном смысле. В твоём случае класс собаки должен выглядеть так:
        ExpandedWrap disabled
          enum LocationType
          {
             Indoor,
             Outdoor
          };
           
          class Dog
          {
          public:
          //...
             void MoveTo(LocationType loc);
          //...
          };

        И появляется класс хозяина:
        ExpandedWrap disabled
          class DogOwner
          {
          public:
             void WalkDog(Dog* d);
          };
          Там же есть аналогичный пример с банковским счетом. Есть класс счета Account

          Должны быть функции "снять со счета" - Transfer, "перевести на другой счет" - Withdraw.
          Теперь начинаются проблемы

          Счет не должен сам с себя снимать. Т.е поместить методы в класс счета плохо.

          Какой вариант выбрать, или оба неправильные?

          ExpandedWrap disabled
            acc.Withdraw(100);//снять 100 рублей со счета acc
            accfrom.Transfer(100,accto);//перевести 100 рублей со счета accfrom на счет accto

          или
          ExpandedWrap disabled
            Withdraw(acc, 100);//снять 100 рублей со счета acc
            Transfer(100,accfrom,accto);/перевести 100 рублей со счета accfrom на счет accto

          В случае выбора второго варианта, нужен ли специальный контейнер для этих функций наподобие
          ExpandedWrap disabled
            class AccountManager
          ?
            Ответ на вопрос про собаку или счета - зависит исключительно от требований задачи! ООП само по себе не диктует единственно верный ответ, хоть ты тресни. ООП - это просто классы и методы, не более того.
            Поэтому подход к проектированию классов напрямую зависит от выбора модели (и её детализации), которую мы будем использовать для решения нашей задачи.

            Если смотреть на реальную жизнь, то больше всего, имхо, ей соответствует вариант с отдельным понятием процесса выгула собаки (перевода денег между счетами) - сервис, менеджер и т.д. И естественно никакого наследования! Это вообще похоже на бред.
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0340 ]   [ 16 queries used ]   [ Generated: 19.04.24, 19:57 GMT ]