对于工厂模式而言,其核心目标应该就是一下一点
专门构建一个类负责提供组件
所以,很容易就可以得到以下几点需求
1.工厂类有可以返回某个组件的方法
2.工厂类应该负责组件之间的依赖
然后,一个简单工厂就这样诞生了
比较常见的,它可以长这样
public class SimpleFactory {
public UserDao getUserDao() {
return UserDaoImpl();
}
public BookDao getBookDao() {
return UserDaoImpl();
}
public UserService getUserService() {
UserService userService = new UserServiceImpl();
userService.setUserDao(this.getUserDao());
userService.setBookDao(this.getBookDao());
return userService;
}
public BookService getBookService() {
BookService bookService = new BookServiceImpl();
bookService.setBookDao(this.getBookDao());
return bookService;
}
}
可以在每个方法里面处理依赖关系,包括 dao 和 service 一般情况下可以处理成单例。如果是静态工厂的话可以这样。
public static BookService getBookService() {
BookService bookService = new BookServiceImpl();
bookService.setBookDao(SimpleFactory.getBookDao());
return bookService;
}
其实并没有多少区别,然后,另外一种常见的形式大概是这样
public class SimpleFactory {
public BaseDao getDao(String name) {
if ("userDao".equals(name)) {
return new UserDaoImpl();
} else if ("bookDao".equals(name)) {
return new BookDaoImpl();
} else {
return null;
}
}
public BaseService getService(String name) {
if ("userService".equals(name)) {
return new UserServiceImpl();
} else if ("bookService".equals(name)) {
return new BookServiceImpl();
} else {
return null;
}
}
}
或者合并在一起变成这样
public Object getBean(String name) {
if ("userDao".equals(name)) {
return new UserDaoImpl();
} else if ("bookDao".equals(name)) {
return new BookDaoImpl();
} else if ("userService".equals(name)) {
return new UserServiceImpl();
} else if ("bookService".equals(name)) {
return new BookServiceImpl();
} else {
return null;
}
}
这两种方法的弊端就是,不能保证一定会获得对象,或者参数写错的话,一定是一件非常让人喜悦的事情。
同样,这两种方法也可以根据不同情况改成静态方法,但是,如果静态方法的弊端就是,很难在构造方法中去处理一些东西,其实最后一种方法已经比较接近平常使用的形式了(大概),如果调用的话会是这个样子。
SimpleFactory factory = new SimpleFactory();
UserDao userDao = (UserDao) factory.getBean("userDao");
构造方法中也可以传递一些配置名字什么的,大概整体会变成这样
public class SimpleFactory {
private Map<String, Object> mDataMap = new HashMap<String, Object>();
public SimpleFactory(String fileName) {
// 正常情况下应该是去读某个xml的,这里就算了
mDataMap.put("userDao", new UserDaoImpl());
mDataMap.put("bookDao", new BookDaoImpl());
mDataMap.put("userService", new UserServiceImpl());
mDataMap.put("bookService", new BookServiceImpl());
}
public Object getBean(String name) {
return mDataMap.get(name);
}
}
如果工厂取出的组件不是要求单例则可以这样
public class SimpleFactory {
private Map<String, Class<?>> mDataMap = new HashMap<String, Class<?>>();
public SimpleFactory(String fileName) {
// 正常情况下应该是去读某个xml的,这里就算了
mDataMap.put("userDao", UserDaoImpl.class);
mDataMap.put("bookDao", BookDaoImpl.class);
mDataMap.put("userService", UserServiceImpl.class);
mDataMap.put("bookService", BookServiceImpl.class);
}
public Object getBean(String name) {
Class<?> cls = mDataMap.get(name);
if (cls == null) {
return null;
}
Object obj = null;
try {
obj = cls.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}
话说随着代码的改动已经看不到 new 关键字了哎,然而,以上并不是一种设计模式,只是简单工厂而已,不过,实际中应该比较常用吧。
工厂方法模式(Factory Method Pattern)
对于工厂模式而言,简单工厂基本上已经足够用了吧,但简单工厂的扩展比较依赖于配置文件,所以,纯粹的代码设计中就有了工厂方法
public interface FoodFactory {
Food getFood(String name);
}
public class StoreFactory implements FoodFactory {
@Override
public Food getFood(String name) {
if ("cake".equals(name)) {
return new Cake();
} else if ("bread".equals(name)) {
return new Bread();
}
return null;
}
}
public class HomeFactory implements FoodFactory {
@Override
public Food getFood(String name) {
if ("bread".equals(name)) {
return new Bread();
}
return null;
}
}
调用的时候大概是这样
FoodFactory factory = new HomeFactory();
Food food = factory.getFood("cake");
而实际上,常见的形式应该是这种
Connection conn = DriverManager.getConnection("");
Statement statment = conn.prepareStatement("sql");
对比之下可以发现,我们如果是有一个新的“食物工厂”,只需要实现那个接口类,而调用方面,如果是用工厂去创建工厂,同样也是去改一行参数,所以,对于一个新的数据库而言,只需要数据库开发者去实现 JDBC 接口,用户方面需要做的也只是去改变创建数据库的参数就可以了。
(以上是我自己编的,正确率有待考证)
PS: 抽象工厂还没看~
end