2015-08-26 3 views
0

Предположим, у нас есть абстрактная фабрика, которая создает для нас некоторые продукты. Мы знаем, что абстрактный завод может предоставить нам некоторые конкретные подклассы продукта, но мы не хотим проверять тип (это основная причина этого шаблона). Теперь нам нужно создать конкретный вид для каждого типа объекта, как мы можем это сделать, не зная конкретного типа? Должна ли та же фабрика создавать разные виды?Дизайн шаблона для создания конкретных элементов вида

Обновление: Я создал github repo, чтобы опробовать всевозможные подходы.

+0

Опубликовать код. –

+0

Да. «_Look & Feel [Abstract Factory] (http://www.oodesign.com/abstract-factory-pattern.html) является наиболее распространенным примером.« – jaco0646

+0

Что такое «вид» в вашем случае? Является ли «вид» тем, что продукт должен знать или заботиться? Можете ли вы иметь несколько разных видов для одного продукта? Могут ли некоторые продукты просматривать, что другие продукты не могут? Предоставление более подробной информации или некоторых примеров даст вам гораздо лучшие предложения. – Groo

ответ

1

По этой проблеме мы можем посмотреть, как абстрактный шаблон фабрики реализован в ADO.NET.

У нас есть абстрактная фабрика под названием DbProviderFactory. Есть несколько реализаций этой фабрики, как SqlClientFactory, MySqlClientFactory, OracleClientFactory и т.д.

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

На первый наш абстрактный завод дает нам соединение (продукт). Это может быть MySqlConnection или OracleConnection. Единственное, что мы знаем, это DbConnection.

DbProviderFactory factory = ... 
DbConnection conn = factory.CreateConnection(); 

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

DbCommand cmd = conn.CreateCommand(); 

Как вы видите, команда (вид) создается соединением (продуктом), а не абстрактной фабрикой.

Но это не совсем верно ...

Что происходит на самом деле скрывается в деталях реализации. Когда абстрактная фабрика создает соединение, она переходит к соединению. И когда мы запрашиваем команду, соединение создает команду через предоставленную абстрактную фабрику.

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

interface IView { 
    IProduct Product { get; set; } 
    void Render(); 
} 

interface IProduct { 
    IView CreateView(); 
} 

interface IAbstractFactory { 
    IProduct CreateProduct(); 
    IView CreateView(); 
} 

class View1 : IView { 
    public IProduct Product { get; set; } 

    public void Render() { 
     Product1 p1 = (Product1)Product; 
     // Do product1 specific rendering here 
    } 
} 

class Product1 : IProduct { 
    private IAbstractFactory factory; 

    public Product1(IAbstractFactory factory) { 
     this.factory = factory; 
    } 

    public IView CreateView() { 
     IView view = factory.CreateView(); 
     view.Product = this; 
     return this; 
    } 
} 

class Factory1 : IAbstractFactory { 
    IProduct CreateProduct() { 
     return new Product1(this); 
    }   

    IView CreateView() { 
     return new View1();    
    }   
} 
+0

Мне очень нравится ваш ответ. Просто добавьте дополнительные разъяснения ... вы в порядке с идеей спросить представление (так что объект UI) непосредственно к модели? – IgnazioC

+1

Если это модель представления (модель, предназначенная для использования в представлениях) и создание объекта (ключевое слово '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' На самом деле абстрактная фабрика действует как [Стратегия] (https://en.wikipedia.org/wiki/Strategy_pattern) в 'Продукте' –

+1

. Ваш пример - это не то, что я бы рекомендовал. Во-первых, 'IView.Product' должен быть установлен другим кодом. Это означает, что вы полагаетесь на будущих разработчиков, чтобы знать об этом и убедиться, что они его установили.Во-вторых, вы бросаете его на конкретный тип. Это снова полностью противоречит философии ООП. Обе проблемы с радостью передают компиляцию, а затем не выполняются во время выполнения. – Groo

Смежные вопросы