我想知道何时需要使用抽象工厂模式。
这是一个例子,我想知道是否有必要。
以上是抽象工厂模式,我的同学推荐。 以下是我的实施。我不认为有必要使用这种模式。
以下是一些核心代码:
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<String, AbstractDao> daoMap=new HashMap<String, AbstractDao>();
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
所以任何事情都可以告诉我这种适应是否必要吗?
-------------------以下内容是为了解释真实的诉讼--------------
我用Dao的例子是因为它很常见,任何人都知道。
事实上,我现在正在工作的是与DAO无关,我正在努力构建一个Web
服务,web服务包含一些将文件转换为其他格式的算法,
例如:net.CreatePDF,net.CreateWord等,它向客户端公开两个接口:getAlgorithms和doProcess。
getAlogrithoms将返回所有算法的id,每个id都被转换为 相应的算法。
调用doProcess方法的用户还将提供他想要的算法ID。
所有算法都扩展了AbstractAlgorithm,它定义了run()方法。
我使用AlogrithmsRepository存储所有算法(来自
)属性文件,它通过Web配置算法的具体java类
service admin)。也就是说,Web服务公开的接口DoProcess是
由具体的算法执行。
我可举一个简单的例子: 1)用户发送getAlgorithms请求:
http://host:port/ws?request=getAlgorithms
然后用户将获得嵌入xml中的算法列表。
<AlgorithmsList>
<algorithm>pdf</algorithm>
<algorithm>word<algorithm>
</AlgorithmsList>
2)用户通过以下方式向服务器发送DoProcess:
http://xxx/ws?request=doProcess&alogrithm=pdf&file=http://xx/Test.word
当服务器接收到这种类型的请求时,它将根据AlgorithmRepostory中的“algorithm”参数(在此请求中为pdf)获取具体的算法实例。并调用方法:
AbstractAlgorithm algo=AlgorithmRepostory.getAlgo("pdf");
algo.start();
然后将pdf文件发送给用户。
BTW,在这个例子中,每个算法类似于sqlDao,AccessDao。 这是图像:现在,AlgorithmRepostory是否需要使用抽象工厂?
答案 0 :(得分:2)
如果要求比较UML的2个设计,UML上的第2个API有以下缺点:
答案 1 :(得分:2)
这两种方法的主要区别在于前者使用不同的DAO工厂来创建DAO,而底部的工厂存储一组DAO并返回对存储库中DAO的引用。
如果多个线程需要访问同一类型的DAO,那么底层方法就会出现问题,因为JDBC连接未同步。
这可以通过让DAO实现一个简单地创建并返回新DAO的newInstance()
方法来解决。
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;
}
<强>更新强>
至于您的问题,您的网络服务应该实现工厂还是可以使用您描述的存储库?答案再次取决于细节:
答案 2 :(得分:0)
如果您需要在创建内容时将多个维度分开,那么抽象工厂非常有用。
在窗口系统的常见示例中,您希望为各种窗口系统创建一系列窗口小部件,并为每个窗口系统创建一个具体工厂,以创建在该系统中工作的窗口小部件。
在构建DAO的情况下,如果您需要为域中的各种实体创建一个DAO系列,并希望创建整个系列的“sql”版本和“访问”版本,则可能很有用。 。这是我认为你的同学正在努力做的事情,如果这就是你正在做的事情,这可能是一个好主意。
如果你只有一件事变化,那就太过分了。