单例模式的学习
- 优化了性能,节省内存开支
- 单例模式一般没有接口,比较难以拓展,这也意味着难以测试(没有mock)
- 单例模式也有线程安全问题(懒汉式可能有线程安全问题)
- 如果实现了cloneable接口,并实现了clone方法,则可以直接通过对象复制的形式创新一个新对象(不用调用构造器),所以单例类最好不实现cloneable接口
工厂设计模式
抽象设计工厂模式
定义一个用于创建对象的
接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类(工厂是个抽象类,可以有多个工厂实现类,
Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂
ConcreteCreator完成的)。
工厂模式优点
- 如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合
- 在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。
- 屏蔽产品类,类似的是数据库中jdbc的使用,切换数据库只用换个数据库链接字符串
工厂模式的拓展
public class Singleton {
//不允许通过new产生一个对象
private Singleton(){
}
public void doSomething(){
//业务处理
}
}
public class SingletonFactory {
private static Singleton singleton;
static {
try {
Class cl = Class.forName(Singleton.class.getName());
// 获得无参构造
Constructor constructor = cl.getDeclaredConstructor();
// 设置无参构造是可访问的
constructor.setAccessible(true);
// 产生一个实例对象
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
// 异常处理
}
}
public static Singleton getSingleton() {
return singleton;
}
}
- 有缓存的工厂
public class ProductFactory {
private static final Map<String, Product> prMap = new HashMap();
public static synchronized Product createProduct(String type) throws Exception {
Product product = null;
//如果Map中已经有这个对象
if (prMap.containsKey(type)) {
product = prMap.get(type);
} else {
if (type.equals("Product1")) {
product = new ConcreteProduct1();
} else {
product = new ConcreteProduct2();
}
//同时把对象放到缓存容器中
prMap.put(type, product);
}
return product;
}
}
抽象工厂模式
互相影响的产品线是一个暗示,可以把产品之间的约束在工厂内部中逻辑实现
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
我们来看看抽象工厂的通用源代码,首先有两个互相影响的产品线(也叫做产品族),
例如制造汽车的左侧门和右侧门,这两个应该是数量相等的——两个对象之间的约束,
每个型号的车门都是不一样的,这是产品等级结构约束的,如以下类图
容易拓展产品等级,但难以拓展产品线,因为这要在抽象接口中增加方法,变动太大