когда использовать шаблон "абстрактная фабрика"?

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

Вот пример, я хочу знать, необходимо ли это.

UML

Вышеупомянутое является шаблоном "абстрактная фабрика", оно рекомендуется моим одноклассником. Следующее является myown implemention. Я не думаю, что необходимо использовать шаблон.

И следующее является некоторыми базовыми кодами:

    package net;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;



public class Test {
    public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
        DaoRepository dr=new DaoRepository();
        AbstractDao dao=dr.findDao("sql");
        dao.insert();
    }
}

class DaoRepository {
    Map daoMap=new HashMap();
    public DaoRepository () throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException  {
        Properties p=new Properties();
        p.load(DaoRepository.class.getResourceAsStream("Test.properties"));
        initDaos(p);
    }
    public void initDaos(Properties p) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        String[] daoarray=p.getProperty("dao").split(",");
        for(String dao:daoarray) {
            AbstractDao ad=(AbstractDao)Class.forName(dao).newInstance();
            daoMap.put(ad.getID(),ad);
        }
    }
    public AbstractDao findDao(String id) {return daoMap.get(id);}

}
abstract class AbstractDao {
    public abstract String getID();
    public abstract void insert();
    public abstract void update();
}
class SqlDao extends AbstractDao {
    public SqlDao() {}
    public String getID() {return "sql";}
    public void insert() {System.out.println("sql insert");}
    public void update() {System.out.println("sql update");}
}
class AccessDao extends AbstractDao {
    public AccessDao() {}
    public String getID() {return "access";}
    public void insert() {System.out.println("access insert");}
    public void update() {System.out.println("access update");}
}

И содержание Test.properties является всего одной строкой:

dao=net.SqlDao,net.SqlDao

Таким образом, какой-либо ont может сказать мне, если этот suitation необходим?


-------------------Следующее добавляется для объяснения реального suitation--------------

Я использую пример Дао, то, потому что это распространено, любой знает это.

На самом деле то, что я работаю теперь, не связано с ДАО, я работаю для создания сети

сервис, сеть serivce содержит некоторые алгоритмы к chang файл к другому формату,

Для example:net. CreatePDF, сеть. CreateWord и и т.д., это выставляет два интерфейса client:getAlgorithms и doProcess.

getAlogrithoms возвратит идентификаторы всех алгоритмов, каждый идентификатор связан с соответствующим алгоритмом.

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

Весь алгоритм расширяет AbstractAlgorithm, которые определяют выполнение () метод.

Я использую AlogrithmsRepository для хранения всех алгоритмов (от

файл свойств, которые конфигурируют конкретные классы Java алгоритмов сетью

сервисный администратор).That's для высказывания интерфейс DoProcess, выставленный веб-сервисом,

выполняемый конкретным алгоритмом.

Я могу дать простой пример: 1) пользователь отправляет getAlgorithms запрос:

http://host:port/ws?request=getAlgorithms

Затем пользователь получит список алгоритмов, встроенных в xml.


  pdf
  word

2) пользователь отправляет DoProcess на сервер:

http://xxx/ws?request=doProcess&alogrithm=pdf&file=http://xx/Test.word

когда сервер получит этот тип requst, это получит конкретный экземпляр алгоритма согласно параметру "алгоритма" (это - PDF в этом запросе) от AlgorithmRepostory. И назовите метод:

AbstractAlgorithm algo=AlgorithmRepostory.getAlgo("pdf");
algo.start();

Затем файл PDF будет отправлен пользователю.

BTW, в этом примере, каждый алгоритм подобен sqlDao, AccessDao. Вот изображение:

Изображение дизайна

Теперь, AlgorithmRepostory должен использовать Абстрактную Фабрику?

5
задан skaffman 24 April 2010 в 16:21
поделиться

3 ответа

Основное различие между двумя подходами заключается в том, что верхний использует разные фабрики DAO для создания DAO, а нижний хранит набор DAO и возвращает ссылки на DAO в репозитории.

Нижний подход имеет проблему, если нескольким потокам требуется доступ к одному и тому же типу DAO одновременно, поскольку соединения JDBC не синхронизируются.

Это можно исправить, если в DAO будет реализован метод newInstance () , который просто создает и возвращает новый DAO.

abstract class AbstractDao {
    public abstract String getID();
    public abstract void insert();
    public abstract void update();
    public abstract AbstractDao newInstance();
}
class SqlDao extends AbstractDao {
    public SqlDao() {}
    public String getID() {return "sql";}
    public void insert() {System.out.println("sql insert");}
    public void update() {System.out.println("sql update");}
    public AbstractDao newInstance() { return new SqlDao();}
}

Репозиторий может использовать DAO в репозитории в качестве фабрик для DAO, возвращаемых репозиторием (который я бы переименовал в Factory в этом случае) следующим образом:

public AbstractDao newDao(String id) {
    return daoMap.containsKey(id) ? daoMap.get(id).newInstance() : null;
}

Обновление

Что касается вашего вопроса, если ваш веб- service реализует фабрику или может использовать репозиторий, как вы описали? Опять же, ответ зависит от деталей:

  • Для веб-сервисов нормально ожидать нескольких одновременных клиентов
  • Поэтому экземпляры, выполняющие процесс для двух клиентов, не должны {{1} }} влияют друг на друга
  • Это означает, что у них не должно быть общего состояния
  • Фабрика доставляет новый экземпляр по каждому запросу, поэтому при использовании шаблона фабрики
  • Если (и только если) экземпляры в вашем репозитории не имеют состояния, ваша веб-служба также может использовать репозиторий , как вы описываете, для этого им, вероятно, потребуется создать экземпляры других объектов для фактического выполнения процесса на основе переданных параметров запроса
2
ответ дан 15 December 2019 в 00:54
поделиться

Если вы попросите сравнить 2 дизайна из UML, второй API на UML имеет следующий недостаток:

  • вызывающий должен явно указать тип DAO при вызове getDAO (). Вместо этого вызывающий не должен заботиться о типе DAO, с которым он работает, если DAO соответствует интерфейсу. Первый дизайн позволяет вызывающему абоненту просто вызвать createDAO () и получить интерфейс для работы. Таким образом, управление тем, какой из имплементов использовать, становится более гибким, и вызывающий абонент не несет этой ответственности, что улучшает общую согласованность дизайна.
2
ответ дан 15 December 2019 в 00:54
поделиться

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

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

В вашем случае создания DAO, это, вероятно, будет полезно, если вам нужно создать семейство DAO для различных сущностей в вашем домене и вы хотите создать версию «sql» и версию «доступа» для всего семейства. . Я думаю, что это то, что пытается донести ваш одноклассник, и если это то, что вы делаете, это, вероятно, будет хорошей идеей.

Если у вас есть только что-то одно, это излишне.

0
ответ дан 15 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: