Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Неполностью реализованные паттерны Oop.

351
25 декабря 2004 года
PitxBull
633 / / 22.12.2004
Green, приведи мне пример не полностью реализованного паттерна OOP. Мне чисто с научной точки зрения интересно.
3
25 декабря 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by PitxBull
Green, приведи мне пример не полностью реализованного паттерна OOP. Мне чисто с научной точки зрения интересно.


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

351
26 декабря 2004 года
PitxBull
633 / / 22.12.2004
Цитата:
Originally posted by Green

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



паттерн Strategy.

3
28 декабря 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by PitxBull

паттерн Strategy.



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

Динамически применяемая стратеги в общем виде представляет собой систему классов включающую:
- интерфейс стратегии, абстрактный класс, либо класс содержащий дефолтовую реализацию некоторых методов;
- конкретные стратегии, порожденные от класса интерфейса;
- контекст, к которому применяется та или иная стратегия, имеющий механизм назначения стратегии и обычно связанный с конкретной стратегией через агрегацию указанеля на интерфейс стратегии.

В общем виде это выглядит так:

Код:
class IStrategy
{
public:
  virtual func1();
  virtual func2();
};

class ConcreteStrategy1
{
public:
  /*virtual*/ func1();
  /*virtual*/ func2();
};

class ConcreteStrategy2
{
public:
  /*virtual*/ func1();
  /*virtual*/ func2();
};

class Context
{
private:
  IStrategy* pStrategy;

public:
  SetStrategy(IStrategy*);
};


Статически применяемые стратегии могут реализовываться через обычное наследование или агрегацию
 
Код:
class Context :ConcreteStrategy1
{
};

class Context
{
  ConcreteStrategy1 strategy;
};

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

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

Как видишь, даже такой примитивный паттерн, как стратегия может быть реализован множеством различных путей. При этом какждый из методов применяется непосредственно от условий и общей архитектуры системы, и может быть реализован так, как это целесообразно в каждом конкретном случае.
Одним словом, жесткой схемы нет. Есть общее понятие, примерное описание некоторой единицы проектирования.
Что же касается рефакторинга, то наглядно видно, что рефакторинг не является способом "приведения кода к конкретному паттерну", т.к. сам код зависит изначально от выбранного на этапе проектирования паттерна.
351
28 декабря 2004 года
PitxBull
633 / / 22.12.2004
Цитата:
Originally posted by Green


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

Динамически применяемая стратеги в общем виде представляет собой систему классов включающую:
- интерфейс стратегии, абстрактный класс, либо класс содержащий дефолтовую реализацию некоторых методов;
- конкретные стратегии, порожденные от класса интерфейса;
- контекст, к которому применяется та или иная стратегия, имеющий механизм назначения стратегии и обычно связанный с конкретной стратегией через агрегацию указанеля на интерфейс стратегии.

В общем виде это выглядит так:
Код:
class IStrategy
{
public:
  virtual func1();
  virtual func2();
};

class ConcreteStrategy1
{
public:
  /*virtual*/ func1();
  /*virtual*/ func2();
};

class ConcreteStrategy2
{
public:
  /*virtual*/ func1();
  /*virtual*/ func2();
};



Спасибо за ликбез. Хочу заметить что на этом определение паттерна Strategy кончается. Это можно утверждать проанализировав различные примеры применения паттерна Strategy. Именно эта часть является постоянной и неизменной - все остальное лишь тот или иной способ его задействования. Например:

Цитата:
Originally posted by Green

 
Код:
class Context
{
private:
  IStrategy* pStrategy;

public:
  SetStrategy(IStrategy*);
};


Статически применяемые стратегии могут реализовываться через обычное наследование или агрегацию
 
Код:
class Context :ConcreteStrategy1
{
};

class Context
{
  ConcreteStrategy1 strategy;
};



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

Еще хотелось бы заметить по поводу:

Цитата:
Originally posted by Green

Статически применяемые стратегии могут реализовываться через обычное наследование...
 
Код:
class Context :ConcreteStrategy1
{
};



Крайне плохое решение. Противоречит базовым принципам OOP. Context не есть разновидность Strategy. Это действительно где то так написано? Если да то плз ссылочку.

Цитата:
Originally posted by Green

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

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



Еще раз спасибо за ликбез.

Цитата:
Originally posted by Green

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



По всей видимости происходит подмена понятий "реализован" и "использован". Кроме того речь шла о "неполной реализации", а не о "вариантах использования".

Цитата:
Originally posted by Green

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



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

3
28 декабря 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by PitxBull

Хочу заметить что на этом определение паттерна Strategy кончается.


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

GoF:

Цитата:

Название

Strategy
Стратегия
паттерн поведения объектов

Участники

Strategy (Compositor) - стратегия:
- объявляет общий для всех поддерживаемых алгоритмов интерфейс. Класс Context пользуется этим интерфейсом для вызова конкретного алгоритма, определенного в классе ConcreteStratecjy;

ConcreteStrategy (SirnpleCompositor, TeXCompositor, ArrayCompositor) - конкретная стратегия:
- реализует алгоритм, использующий интерфейс, объявленный в классе Strategy;

Context (Composition) - контекст:
- конфигурируется объектом класса ConcreteStrategy;
- храпит ссылку на объект класса Strategy;
- может определять интерфейс, который позволяет объекту strategy получить доступ к данным контекста.




Цитата:
Originally posted by PitxBull

Крайне плохое решение. Противоречит базовым принципам OOP. Context не есть разновидность Strategy. Это действительно где то так написано? Если да то плз ссылочку.


А.Александреску, "Современное проектирование на С++" ("Modern C++ Design"), стр.31
1.5 Стратегии и классы стратегий

Цитата:

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



Цитата:
Originally posted by PitxBull

По всей видимости происходит подмена понятий "реализован" и "использован". Кроме того речь шла о "неполной реализации", а не о "вариантах использования".


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

"Неполная реализация" - это твоя формулировка, к которой я не имею отношения.

Само понятие "неполной реализации" не имеет смысла, т.к. паттерн это не что-то фиксированное, жестко лимитированное. Цитирую себя же:

Цитата:

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



Цитата:

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




Цитата:
Originally posted by PitxBull

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


Любой из "общепризнанных паттернов" можно реализовать множеством способов и т.о. сама реализация подлежит рефакторингу.

Цитата:
Originally posted by PitxBull

Но в частности в моей практике я так сказать "рефакторизировал" код как раз на предмет приведения его к тому или иному паттерну(ЯВНО).


Значит, изначально код не был спроектирован.
Приведение готового кода к паттерну, - это подгонка под ответ, что не есть правильно. Я уже говорил об этом, что при нормальном проектировании пляшут от обратного: сначала проектируют на уровне паттернов, потом реализуют в виде кода.

Цитата:
Originally posted by PitxBull

После это больше необходимостей в рефакторизации этого участка кода больше не возникало. Аминь.


Да будет земля пухом этому коду.

P.S. Что там с сабклассингом без внедрения?

351
16 января 2005 года
PitxBull
633 / / 22.12.2004
Цитата:
Originally posted by Green

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

GoF:



Ничего я не путаю. Мне кажется ты не понимаешь сути паттерна Strategy. Классы Context и Client - всего лишь способ задействования IStrategy, основная суть паттерна именно в этом как ты говоришь всего лишь только участнике. На самом деле в неигрушечных примерах классы Context и Client строго говоря не являются только учасниками данного паттерна. В частности в моем текущем проекте(файловый менеджер) класс Context - он же участник(как ты выражаешься, я думаю может - соучастник :D), друго паттерна - Mediator, он же основное окно, и у него даже есть Client - CWinApp. Если же придерживаться строго формальных определений до можно договориться до полного бреда, примеров тому в юриспруденции наверное миллионы, но мы же не в американском суде? :D

3
16 января 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by PitxBull

На самом деле в неигрушечных примерах классы Context и Client строго говоря не являются только учасниками данного паттерна. В частности в моем текущем проекте(файловый менеджер) класс Context - он же участник(как ты выражаешься, я думаю может - соучастник :D), друго паттерна - Mediator, он же основное окно, и у него даже есть Client - CWinApp.


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

Границы паттерна не являются границами класса или классов. Другими словами, класс может входить в несколько паттернов, реализовывать в каждом из них нескольких участников. Обычно так и происходит, т.е. как я утверждаю с самого начала, ВСЁ ЗАВИСИТ ОТ КОНКРЕТНОЙ РЕАЛИЗАЦИИ.

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

Докажи мне, плз, документально, что

Цитата:
Originally posted by PitxBull

код изначально написанный по тому или иному общепризнаному паттерну вряд ли подлежит "рефакторизации"



Ну а вообще-то, мне уже надоело это толчение воды в ступе. Если ты считаешь, что твоё видиние паттернов правильное, - удачи, я отговаривать не собираюсь... с моим то отрицательным IQ...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог