工厂建设之路-- 简单工厂
Posted barneycs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂建设之路-- 简单工厂相关的知识,希望对你有一定的参考价值。
为什么要用工厂?
用工厂的主要目的是把对象的创建和使用分离,这比较符合单一职责原则,工厂负责创建产品,调用者负责使用产品,如果调用者既需要负责创建产品又需要负责使用产品,那么耦合性会比较高。
以一个常见的登录功能为例:
class HibernateUserDao {
public void getUser() {
System.out.println("Hibernate get user");
}
}
public class UserService {
private MybatisUserDao userDao;
public UserService() {
this.userDao = new MybatisUserDao();
}
public void login() {
userDao.getUser();
}
}
这样的坏处是什么呢?我们发现UserService的责任太重,不仅要创建UserDao的实例对象还要调用。假如现在公司为了统一项目都换成MyBatis那么更改起来非常麻烦。
简单工厂
我们对代码稍作修改:
/**
* UserDao作为产品让工厂创建
*/
public interface UserDao {
void getUser();
}
/**
* UserDao的不同实现
*/
class MybatisUserDao implements UserDao {
@Override
public void getUser() {
System.out.println("Mybatis get user");
}
}
class HibernateUserDao implements UserDao {
@Override
public void getUser() {
System.out.println("Hibernate get user");
}
}
public class UserService {
private UserDao userDao;
public UserService(String name) {
this.userDao = new MybatisUserDao();
}
public void login() {
userDao.getUser();
}
}
public class Factory {
public static UserDao getUserDao(String name) {
switch (name) {
case "mybatis":
return new MybatisUserDao();
case "hibernate":
return new HibernateUserDao();
default:
return null;
}
}
}
- 这样无论是创建MyBatis还是Hibernate的UserDao客户端都可以自由选择。
- 还有一个好处,UserDao这种对象往往不在一个地方被创建,如果用工厂统一管理起来,修改起来更方便,只需要修改一个Factory类就可以处处生效。
但是这里有一个问题,我们发现简单工厂模式并不符合开闭原则,如果我们又需要增加UserDao的实现或者创建有所变动的话还是需要修改Factory类,并且客户端需要更改传入的值。在实际开发中可以通过配置文件替代传入的参数,这样可以避免修改客户端,而只需要配置不同的配置文件从而实现代码的复用。
简单工厂并不是GOF23种设计模式之一,但是它是工厂方法和抽象工厂模式的基本形态,工厂方法和抽象工厂由它演变而来。
餐后甜点
我们来看一下JDK中的Integer的创建方式:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们可以认为他把Integer的工厂和产品合并了,valueOf作为生产方法,这样做的好处是客户端使用这个方法可以用到IntegerCache的常量池优化,如果直接new就没有优化了。使用常量池也可以看做享元模式的思想,后面的博客会说到。
以上是关于工厂建设之路-- 简单工厂的主要内容,如果未能解决你的问题,请参考以下文章