简单工厂模式
代替new的实例化对象的设计模式,属于创建型设计模式
特点:面向接口编程,实例化对象的逻辑对于用户而言是透明的
摘自菜鸟教程的介绍:
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
看看 java.lang.Class的源码
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
}
---> return newInstance0();
}
加载任何的具体类,只需调用newInstance方法即可创建对应的实例;修改具体实现类时,创建实例的代码不需要做任意的修改。
public T createT(){ //T是泛型
Class c = Class.forName(className);//className可配置
T t = c.newInstance();
return t;
}
T作为接口,利用面向对象多态特性,如果需要修改具体的实现类(遵循借口T规范),只需要修改className路径下的类即可,创建实例的方法没有任何改变
扩展性是不是很棒棒
比较容易理解的运用案例:
Hibernate 换数据库只需换方言和驱动就可以 ---- 快速切换数据库
抽象工厂模式
工厂的工厂,主要是运用来实例化一个族的对象
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
以上图为例子,AbstractFactory中Shade/Color是一族关联的类,getShade/getColor是两个抽象方法,
Concrete具体假设就是 FeatureFactory
public class FeatureFactory00{
Shade getShade(){ return new Circle();}
Color getColor(){ return new Red();}
}
public class FeatureFactory01{
Shade getShade(){ return new Square();}
Color getColor(){ return new Blue();}
}
FeatureFactory00/FeatureFactory00是AbstractFactory的具体实现类,各包含一组Shade/Color
如上图FactoryProducter会根据工厂方法产生具体工厂类,具体工厂类再对应一族关联的类;更换具体工厂类也就是
更换一组类。
抽象工厂模式的优点
-
-
- 分离接口和实现
-
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
-
-
- 使切换产品族变得容易
-
因为一个具体的工厂实现代表的是一个产品族
抽象工厂模式的缺点
- 不太容易扩展新的产品
如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
注: 随笔部分参考,如有雷同处,请见谅