Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Паттерны проектирования, благо или зло? 
:(
    Опции темы
k0rvin
Дата 15.7.2010, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



есть такой код на С++:
Код

namespace geom_obj {
    enum type { triangle = 1, circle, square };
}

class CFigure;
class CTriangle;
class CCircle;
class CSquare;

struct CFactory
{
   static CFigure* CreateObject(const geom_obj::type obj_type)
   {
      switch(obj_type)
      {
        case geom_obj::circle:   return new CCircle(); break;
        case geom_obj::square:   return new CSquare(); break;
        case geom_obj::triangle: return new CTriangle(); break;
        default: printf("unknown object...");
      }
      return 0;
   }
};

class CFigure {
   virtual void draw() = 0;
};

class CTriangle: public CFigure {
public:
   virtual void draw() { printf("CTriangle"); }
};

class CCircle: public CFigure {
public:
   virtual void draw() { printf("CCircle"); }
};

class CSquare: public CFigure {
public:
   virtual void draw() { printf("CSquare"); }
};

int main()
{
   CFigure * obj = CFactory::CreateObject(geom_obj::triangle);
   obj->draw();
   obj = CFactory::CreateObject(geom_obj::circle);
   obj->draw();
   obj = CFactory::CreateObject(geom_obj::square);
   obj->draw();

   delete obj;

   return 0;
}


товарищ, который его мне привёл, утверждает, что он (код) реализует паттерн проектирования "Фабрика" (ну или как-то так, за название не ручаюсь =))

я тут вижу весьма эээ... слабую расширяемость этого паттерна/кода (кто не видит, попробуйте унаследовать от CFigure ещё один клас и создать его экземпляр фабрикой не меняя при этом сорцы CFactory и geom_obj::type)

у каково ваше мнение на счёт паттернов? зло или благо? как бы вы реализовали этот паттерн (с устранением того недостатка расширяемости, что я указал) на вашем любимом ЯП?

Добавлено @ 20:42
да, я сам реализовывал аналоги на Scheme (их было несколько), без использования всяких готовых ООП-систем как в PLT Scheme, их было несколько и вдаваться в подробности я не стану, тем более, что Scheme использует динамическую типизацию, а С++ статическую, однако приведу код на Object Pascal (другого) товарища, который (код) реализует ту же функциональность, но лишён недостатка расширяемости:
Код

type
  TFigure = class
  public
    procedure Draw; virtual;
    constructor Create; virtual;
  end;
  TFigureClass = class of TFigure;

  TTriangle = class(TFigure)
  public
    procedure Draw; override;
  end;

  TCircle = class(TFigure)
  public
    procedure Draw; override;
  end;

  TSquare = class(TFigure)
  public
    procedure Draw; override;
  end;

  TFactory = class(TObject)
  public
    class function CreateObject(AClass: TFigureClass): TFigure;
  end;

class function TFactory.CreateObject(AClass: TFigureClass): TFigure;
begin
  Result:=AClass.Create;
end;

procedure TFigure.Draw;
begin
end;

constructor TFigure.Create;
begin
end;

procedure TSquare.Draw;  
begin
  writeln('Square');
end;

procedure TCircle.Draw;  
begin
  writeln('Draw');
end;

procedure TTriangle.Draw;  
begin
  writeln('Triangle');
end;

var
  f :TFigure;

begin
  f := TFactory.CreateObject(TTriangle);
  f.Draw; F.Free;
  f : =TFactory.CreateObject(TCircle);
  f.Draw; F.Free;
  f := TFactory.CreateObject(TSquare);
  f.Draw; F.Free;
  readln;
end.


Это сообщение отредактировал(а) k0rvin - 15.7.2010, 20:52


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
Abyx
Дата 15.7.2010, 21:19 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: нет
Всего: 10



k0rvin, это абстрактная фабрика, aka виртуальный конструктор. Погуглите.

Насчет реализации на С++  - почитайте Александреску, там есть более удобная реализация.
PM MAIL   Вверх
k0rvin
Дата 15.7.2010, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(Abyx @ 15.7.2010,  21:19)
k0rvin, это абстрактная фабрика, aka виртуальный конструктор. Погуглите.

Насчет реализации на С++  - почитайте Александреску, там есть более удобная реализация.

как бы в Object Pascal виртуальный конструктор "из каробки" и лишён ограничений расширяемости, присутствующем в приведённом мной коде на С++.

если Вам не сложно, скопипастите пример Александреску сюда.


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
kemiisto
Дата 15.7.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 3
Всего: 160



Цитата(k0rvin @  15.7.2010,  21:38 Найти цитируемый пост)
товарищ, который его мне привёл, утверждает, что он (код) реализует паттерн проектирования "Фабрика" (ну или как-то так, за название не ручаюсь =))

Да, это фабрика. Однако как Вы правильно указали, реализация в таком виде не позволяет использовать преимущества паттерна. 

Когда в реализации этого паттерна наблюдается куча if...then...else или switch, реализацию клеймят как нубскую. Почитайте, например, здесь. Там же есть варианты ненубской реализации. Ваш код на Delphi тоже ничего.

Добавлено через 1 минуту и 2 секунды
Цитата(Abyx @  15.7.2010,  22:19 Найти цитируемый пост)
k0rvin, это абстрактная фабрика, aka виртуальный конструктор. Погуглите.

Абстрактная фабрика и фабрика - разные паттерны проектирования. Скажем, у GoF последний даже не описан.


--------------------
PM MAIL WWW GTalk Jabber   Вверх
k0rvin
Дата 15.7.2010, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(kemiisto @ 15.7.2010,  21:26)
Цитата(k0rvin @  15.7.2010,  21:38 Найти цитируемый пост)
товарищ, который его мне привёл, утверждает, что он (код) реализует паттерн проектирования "Фабрика" (ну или как-то так, за название не ручаюсь =))

Да, это фабрика. Однако как Вы правильно указали, реализация в таком виде не позволяет использовать преимущества паттерна. 

Когда в реализации этого паттерна наблюдается куча if...then...else или switch, реализацию клеймят как нубскую. Почитайте, например, здесь. Там же есть варианты ненубской реализации. Ваш код на Delphi тоже ничего.

ясно, спс за разъяснения, я так и думал, что "что-то не так" в этом коде =)

а код на паскале не мой =)

Добавлено через 2 минуты и 50 секунд
kemiisto,

может выскажетесь относительно "паттернов проектирования -- благо или зло?", как вопрос поставлен в топике (описании топика)? ради этого затевался топик в общем-то, любопытно Ваше мнение.


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
Mephisto
Дата 16.7.2010, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: 1
Всего: 34



Цитата(k0rvin @  15.7.2010,  22:36 Найти цитируемый пост)
может выскажетесь относительно "паттернов проектирования -- благо или зло?", как вопрос поставлен в топике (описании топика)? ради этого затевался топик в общем-то, любопытно Ваше мнение. 

1) Если программист не пользуется шаблонами проектирования, то его код никому нафиг не нужен, по крайней мере мне, как руководителю отдела, точно. Изучать устройство "нового велосипеда" написанного под воздействием каких-то грибов - долго и дорого для проекта. Заменяемость человека практически никакая. 
2) Шаблоны проектирования это не только общепринятые приемы. Да общепринятыми они стали не из-за того чтоб просто сделать что-то общепринятым smile Это достаточно хорошо продуманные реализации часто встречаемых задач в архитектуре программного обеспечения. Как бонус, многие только после знакомства с шаблонами начинают въезжать в ООП. Потому как писать объектно-ориентированные программы и пользоваться классами это совершенно две разные концепции в программировании smile. Я не раз видел как люди слонов наследовали от автомобиля только для того чтоб поместить его в гараж.

Это сообщение отредактировал(а) Mephisto - 16.7.2010, 09:01
PM   Вверх
kemiisto
Дата 16.7.2010, 09:39 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 3
Всего: 160



Цитата(k0rvin @  15.7.2010,  22:36 Найти цитируемый пост)
благо или зло?

Ни то, ни другое.

1) Начать надо вот с чего. Обычно, когда речь идёт о паттернах проектирования, подразумеваются оные, описанные у GoF. И некоторые другие в книгу не вошедшие. Сразу надо отметить, что эти паттерны имеет смысл использовать только в императивных языках со строгой статической типизацией. Наример, Java. Посмотрите, как много примеров GoF-паттернов практически в чистом виде можно обнаружить в стандартных библиотеках этой платформы.

Но если мы используем функциональный ЯП паттерны будут совсем иные. Если гибридный ЯП (Scala, например) - опять-таки свой набор паттернов.

2) Паттерны - суть есть шаблонные решения. В чистом виде встречаются редко. И даже более того... Вот Mephisto отметил выше, что изучение паттернов (он имел ввиду GoF-паттерны) позволяет понять ООП. Верно. Но можно пойти и другой дорогой. Не знать никаких паттернов, а знать пару-тройку правил "хорошего" ООП. Скажем, по возможности наследованию предпочитать композицию, писать как можно более несвязанные классы, разрешать объектам общаться только посредством передачи сообщения, ... В итоге код будет содержать решения близкие по архитектуре к паттернам. 
Цитата
We used design patterns in the 80's, we just didn't know they were design patterns.
 ©

3) По большому счёта паттерны/антипаттерны - просто очень хорошо изученные и систематизированные примеры, показывающие, что такое хорошо и что такое плохо. Поэтому знать надо, но слепо и бездумно использовать везде и всегда - увольте. У любого шаблонного решения есть недостатки. Именно потому, что оно шаблонное. Специфика конкретной задачи может столько ярко обножить эти недостатки, что лучше паттерн и вовсе не использовать. А написать что-то близкое по смыслу, но лишённое того недостатка.

Это сообщение отредактировал(а) kemiisto - 16.7.2010, 09:40


--------------------
PM MAIL WWW GTalk Jabber   Вверх
k0rvin
Дата 16.7.2010, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(Mephisto @ 16.7.2010,  08:55)
Потому как писать объектно-ориентированные программы и пользоваться классами это совершенно две разные концепции в программировании smile. Я не раз видел как люди слонов наследовали от автомобиля только для того чтоб поместить его в гараж.

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

(define (make-object slot-1 slot-2 ...)
  (define (method-1 arg-1-1 ...) ...)
  (define (method-2 arg-2-1 ...) ...)
  ...
  (define (dispatch message)
    (case message
      ((message-1) method-1)
      ((message-2) method-2)
      ...
      (else (error 'dispatch "unknown message: ~e" message))))
  dispatch)


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


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
kemiisto
Дата 16.7.2010, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 3
Всего: 160



Цитата(k0rvin @  16.7.2010,  19:17 Найти цитируемый пост)
а не подскажете есть ли какая русскоязычная статья, где анализируются методы реализации наследования и/или сама концепция наследование вообще

Дык у GoF по сути вся первая глава. Конкретно 1.6 Как решать задачи проектирования с помощью паттернов, после заголовка "Механизмы повторного использования" идёт обсуждение.

На стр.35 вторым правилом объектно-ориентированного проектирования курсивом декламируется: 
Цитата
предпочитайте композицию наследованию класса.


P.S. Вообще, по ООП (пускай и применимок проектированию ОС) есть одна зачётная диссертация. Но на английском. Сам сейчас читаю. smile 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
k0rvin
Дата 16.7.2010, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(kemiisto @ 16.7.2010,  20:19)
P.S. Вообще, по ООП (пускай и применимок проектированию ОС) есть одна зачётная диссертация. Но на английском. Сам сейчас читаю. smile

шрифт там ужасен... английский, к сожалению недостаточно знаю, буду читать GoF =/


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
Mephisto
Дата 18.7.2010, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: 1
Всего: 34



Цитата(k0rvin @  16.7.2010,  19:17 Найти цитируемый пост)
сама концепция наследование вообще

Если вообще об объектно-ориентированном программировании, то вот это хорошая книга.
А если конкретно рассматривать наследование, то 
Цитата(kemiisto @  16.7.2010,  21:19 Найти цитируемый пост)
предпочитайте композицию наследованию класса.

хороший совет, но требует уже достаточного высокого понимания концепции. Жить с таким принципом не так легко, иногда это приводит к ненужному усложнению, по сему нужно четко понимать когда все-таки лучше наследование, а когда агрегация.
Для начала я бы дал совет проверять себя следующим образом:
Когда один класс наследуешь от другого нужно делать следующую проверку: вставлять между словами слово "это". Например: Опель это автомобиль, слон это животное, чайка это птица.
Наследовать один класс от другого можно в том случае, когда ответ однозначно утвердительный.
Если взять мой же пример из предыдущего поста, со слоном, то может получится следующая ситуация:
Наследуем слона от автомобиля чтобы воткнуть в гараж. Получаем "слон это автомобиль = неправда". 
Почему это плохо? Потому что может возникнуть ситуация когда тебе нужно будет пересчитать автомобили на проезжей части, если у тебя по проезжей части будет идти слон, то количество автомобилей получишь в результате больше на единицу.
Если все-таки возникает задача поместить слона в гараж, а гараж только и принимает что автомобили, то следует не слона наследовать от автомобиля, что приведет к ошибке, а перепроектировать класс гаража чтоб он мог поместить и автомобили и слонов.
PM   Вверх
k0rvin
Дата 19.7.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(Mephisto @ 18.7.2010,  20:34)
Цитата(k0rvin @  16.7.2010,  19:17 Найти цитируемый пост)
сама концепция наследование вообще

Если вообще об объектно-ориентированном программировании, то вот это хорошая книга.
А если конкретно рассматривать наследование, то 
Цитата(kemiisto @  16.7.2010,  21:19 Найти цитируемый пост)
предпочитайте композицию наследованию класса.

хороший совет, но требует уже достаточного высокого понимания концепции. Жить с таким принципом не так легко, иногда это приводит к ненужному усложнению, по сему нужно четко понимать когда все-таки лучше наследование, а когда агрегация.
Для начала я бы дал совет проверять себя следующим образом:
Когда один класс наследуешь от другого нужно делать следующую проверку: вставлять между словами слово "это". Например: Опель это автомобиль, слон это животное, чайка это птица.
Наследовать один класс от другого можно в том случае, когда ответ однозначно утвердительный.
Если взять мой же пример из предыдущего поста, со слоном, то может получится следующая ситуация:
Наследуем слона от автомобиля чтобы воткнуть в гараж. Получаем "слон это автомобиль = неправда". 
Почему это плохо? Потому что может возникнуть ситуация когда тебе нужно будет пересчитать автомобили на проезжей части, если у тебя по проезжей части будет идти слон, то количество автомобилей получишь в результате больше на единицу.
Если все-таки возникает задача поместить слона в гараж, а гараж только и принимает что автомобили, то следует не слона наследовать от автомобиля, что приведет к ошибке, а перепроектировать класс гаража чтоб он мог поместить и автомобили и слонов.

а как так вариант, напирмер:
Код

(defclass automobile () ())

(defclass animal () ())

(defclass can-be-in-garage () ())

(defclass opel (automobile can-be-in-garage) ())

(defclass elephant (animal can-be-in-garage) ())

?


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
kemiisto
Дата 19.7.2010, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 3
Всего: 160



k0rvin, в LISP'ах я не в зуб ногой. 

Но, вроде как, это примеси. Недостатков множественного наследования тут нет, но есть другие ограничения. Но это несколько иная история...


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Mephisto
Дата 20.7.2010, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Волкъ
***


Профиль
Группа: Завсегдатай
Сообщений: 1818
Регистрация: 27.8.2003
Где: Питер

Репутация: 1
Всего: 34



k0rvin, можно, если класс can-be-in-garage имеет смысл помимо этого. 
Я бы вводил интерфейс а ля:
Код

public interface IMeasurable
{
    int GetLength();
    int GetWidth();
    int GetHeight();
}

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

Добавлено через 1 минуту и 39 секунд
Потому как в один гараж можно помещать автомобили, но камаз, хоть и автомобиль не в каждый гараж по своим габаритам влазит.
PM   Вверх
k0rvin
Дата 20.7.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: 1
Всего: 5



Цитата(kemiisto @ 19.7.2010,  22:07)
k0rvin, в LISP'ах я не в зуб ногой. 

Но, вроде как, это примеси. Недостатков множественного наследования тут нет, но есть другие ограничения. Но это несколько иная история...

не, судя по 
Цитата
не предназначен для порождения самостоятельно используемых объектов
 это определённо не примеси, ибо все классы в моём примере -- обычные, способные порождать объекты. хотя если ориентироваться на эту цитату из статьи:
Цитата

Методы определяются в другом месте, как в Flavors и CLOS

то да.

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

Это сообщение отредактировал(а) k0rvin - 20.7.2010, 18:49


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила ведения Религиозных войн
Smartov
1. Уважайте собеседника
2. Собеседник != враг
3. Старайтесь воздерживаться от тем вида "Windows Rulez" или "Linux Rulez"

С уважением, Smartov.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Религиозные войны | Следующая тема »


 




[ Время генерации скрипта: 0.1034 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.