Расширение обе стороны Посетителя / шаблон Bridge

голоса
3

Скажем , у меня есть иерархия классов, давайте использовать классические Shapeпримеры:

abstract class Shape
Circle : Shape
Square : Shape

У меня есть вторая иерархия классов визуализатора, которые обрабатывают рендеринг форм по-разному:

abstract class ShapeRenderer
HtmlShapeRenderer : ShapeRenderer
WindowsFormsShapeRenderer : ShapeRenderer

С учетом этих изменяться независимо друг от друга будут традиционно связаны с использованием шаблона Bridge. Позволяя рендеринг действие будет продлено без изменения Shapeклассов будет традиционно включать шаблон для посетителей.

Тем не менее, оба они сосредоточены исключительно на расширение в сторону реализации , а не на стороне абстракции. Скажем , я хотел бы добавить новый Shape, скажем , Triangle- я хочу , чтобы иметь возможность поддерживать отдавая , Triangleа также. Так как посетители и модель моста полагаться на «уплощение» иерархии абстракции в набор методов, например:

public abstract class ShapeRenderer
{
     public abstract void RenderCircle(Circle c);
     public abstract void RenderSquare(Square s);
}

Единственный способ расширить Shapeиерархию, чтобы изменить код базового ShapeRendererкласса, который является критическим изменением.

Джон, чтобы уточнить: Использование моста или Visitor позволяет клиентам обеспечить реализацию альтернативных рендеринга, но требует от них , чтобы знать обо всех возможных формах. То , что я хотел бы быть в состоянии сделать это , чтобы клиенты могли также иметь возможность расширить Shapeкласс и требуют их , чтобы обеспечить оказание реализации своего нового класса. Таким образом, существующий код может работать с любым типом Shape, не заботясь о частностях оказания им.

Есть ли общее решение такого рода проблемы, используемой в C #?

Задан 09/12/2008 в 18:00
источник пользователем
На других языках...                            


4 ответов

голоса
2

Как насчет шаблона стратегии ? Если стратегия является ссылкой на реализацию RenderEngine. Если вы хотите добавить новую форму, создать новую реализацию рендеринга двигателей , которые знают о новой реализации Shape и реализует соответствующую функцию рендеринга. Вы добавляете виртуальную функцию Shape , которая выступает в качестве вспомогательной функции для выбора правильной функции рендеринга формы - то есть объекты Circle вызова функции renderCircle () и т.д.

В C ++, который может выглядеть примерно так:

class Triangle : public Shape
{
  public:
      Triangle( const RenderEngine& whichRenderEngine );
      void render( void ) { renderStrategy->renderTriangle( *this );

  private:
      RenderEngine* renderStrategy;
};

class TriangleRender : HTMLShapeRender
{
   public:
      // if inheriting from concrete class, all other rendering functions 
      // already exist... otherwise re-implement them here.

      void renderTriangle( const Triangle& t ) { /* impl */ }
};

HTMLRenderer r; // doesn't know about Triangles.
Circle c( &r );
c.render();

Square s( &r );
s.render();

// Now we add Triangle
TriangleRenderer tr;
Triangle t( &tr );
t.render();

Square s2( &tr );  // tr still knows how to render squares... 
s2.render();
Ответил 10/12/2008 в 04:50
источник пользователем

голоса
2

Я думаю , что это должно быть нарушение изменений. Если добавить форму, существующие рендеры явно не собираются быть в состоянии справиться - они должны быть изменены.

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

Какой неразрывных изменений вы действительно надеетесь достичь?

Ответил 09/12/2008 в 18:17
источник пользователем

голоса
1

Мое решение здесь почти определенно будет использовать Abstract Factory, в этом случае я бы загрузить словарь ShapeRenderers по типу введенному пользователю, где типа является подклассом Shape и пусть завод обеспечивает ShapeRenderer необходимое для каждой формы (и возможно, платформы, например. окно, Web, iPhone).

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

Ответил 09/12/2008 в 18:58
источник пользователем

голоса
1

Дизайн для интерфейса не реализации.

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

Я не уверен, что я бы с классом ShapeRenderer. Как насчет IRenderHTML, IRenderWindows, которые реализуются классами формы?

Вы получаете расширяемость с формами, а также с Renderings.

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

Ответил 09/12/2008 в 18:22
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more