工厂模式实现了建立者和调用者的分离,实现了更好的解耦。java
详细分类:程序员
1) 简单工厂模式(静态工厂模式);
2) 工厂方法模式;编程
3) 抽象工厂模式ide
面向对象设计的基本原则:工具
1) OCP(开闭原则, Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。ui
2) DIP(依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。编码
3) LoD(迪米特法则, Law of Demeter):只与你直接的朋友通讯,而避免和陌生人通讯。spa
我喜欢吃面条,抽象一个面条基类,(接口也能够),这是产品的抽象类。设计
1 public abstract class INoodles { 2 /** 3 * 描述每种面条啥样的 4 */ 5 public abstract void desc(); 6 }
先来一份兰州拉面(具体的产品类):3d
1 public class LzNoodles extends INoodles { 2 @Override 3 public void desc() { 4 System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗"); 5 } 6 }
程序员加班必备也要吃泡面(具体的产品类):
1 public class PaoNoodles extends INoodles { 2 @Override 3 public void desc() { 4 System.out.println("泡面好吃 可不要贪杯"); 5 } 6 }
还有我最爱吃的家乡的干扣面(具体的产品类):
1 public class GankouNoodles extends INoodles { 2 @Override 3 public void desc() { 4 System.out.println("仍是家里的干扣面好吃 6块一碗"); 5 } 6 }
准备工做作完了,咱们来到一家“简单面馆”(简单工厂类),菜单以下:
1 public class SimpleNoodlesFactory { 2 public static final int TYPE_LZ = 1;//兰州拉面 3 public static final int TYPE_PM = 2;//泡面 4 public static final int TYPE_GK = 3;//干扣面 5 6 public static INoodles createNoodles(int type) { 7 switch (type) { 8 case TYPE_LZ: 9 return new LzNoodles(); 10 case TYPE_PM: 11 return new PaoNoodles(); 12 case TYPE_GK: 13 default: 14 return new GankouNoodles(); 15 } 16 } 17 }
简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:
1 /** 2 * 简单工厂模式 3 */ 4 INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK); 5 noodles.desc()
要点:
1)简单工厂模式也叫静态工厂模式,就是工厂类通常使用静态方法,经过接收的参数的不一样的对象的不一样来返回不一样的对象实例。
2)对于增长新产品无能为力!不修改代码的话,是没法扩展的。
3)通常使用较多仍是简单工厂模式。
工厂方法模式要点:
1)为了不简单工厂模式的缺点,不彻底知足OCP(开闭原则)。
2)工厂方法模式和简单工厂模式最大的不一样在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。
Car.java接口的源码:
工厂方法模式更加符合开闭原则。弊端是每次扩展都会增长新的类。
1)结构复杂度
从这个角度比较,显然简单工厂模式要占优,简单工厂模式只须要一个工厂类,而工厂方法模式的工厂类随着产品类的个数增长而增长,这无疑会使类的个数愈来愈多,从而增长告终构的复杂程度。
2)代码复杂度
代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面确定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增长须要增长更多方法(或代码)。
3)客户端编程难度
工厂方法模式虽然在工厂类结构中引入了接口从而知足了OCP,可是在客户端编码中须要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优势。
4)管理上的难度
这是个关键的问题。
咱们先谈扩展。众所周知,工厂方法模式彻底知足OCP,即它有很是良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否认的,简单工厂模式一样具有良好的扩展性-----扩展的时候仅须要修改少许的代码(修改工厂类的代码)就能够知足扩展性的要求了。尽管这没有彻底知足OCP,但咱们不须要太拘泥于设计理论,要知道,sun提供的java官方工具包中也有不少没有知足OCP的例子啊。
而后咱们从维护性的角度分析下,假如某个具体产品类须要进行必定的修改,极可能须要修改对应的工厂类。当同时须要修改多个产品类的时候,对工厂类的修改会变得至关麻烦(对号入座已是个问题了)。反而简单工厂没有这些问题,当多个产品类须要修改时,简单工厂模式仍然仅仅须要修改惟一的工厂类(不管怎样都能改到知足要求吧?大不了把这个类重写)。
根据设计理论建议:工厂方法模式。但实际上,咱们通常都用了简单工厂模式。
定义:为建立一组相关或相互依赖的对象提供一个接口,并且无需指定他们的具体类。
类型:建立类模式
类图:
抽象工厂模式与工厂方法模式的区别
抽象工厂模式是工厂方法模式的升级版本,他用来建立一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,一般一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的全部产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不一样的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不一样产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。咱们依然拿生产汽车的例子来讲明他们之间的区别。
在上面的类图中,两厢车和三厢车称为两个不一样的等级结构;而2.0排量车和2.4排量车则称为两个不一样的产品族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另外一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另外一个产品族。
明白了等级结构和产品族的概念,就理解工厂方法模式和抽象工厂模式的区别了,若是工厂的产品所有属于同一个等级结构,则属于工厂方法模式;若是工厂的产品来自多个等级结构,则属于抽象工厂模式。在本例中,若是一个工厂模式提供2.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;若是一个工厂模式是提供2.4排量两厢车和2.4排量三厢车两个产品,那么这个工厂模式就是抽象工厂模式,由于他提供的产品是分属两个不一样的等级结构。固然,若是一个工厂提供所有四种车型的产品,由于产品分属两个等级结构,他固然也属于抽象工厂模式了。
1 interface IProduct1 { 2 public void show(); 3 } 4 interface IProduct2 { 5 public void show(); 6 } 7 8 class Product1 implements IProduct1 { 9 public void show() { 10 System.out.println("这是1型产品"); 11 } 12 } 13 class Product2 implements IProduct2 { 14 public void show() { 15 System.out.println("这是2型产品"); 16 } 17 } 18 19 interface IFactory { 20 public IProduct1 createProduct1(); 21 public IProduct2 createProduct2(); 22 } 23 class Factory implements IFactory{ 24 public IProduct1 createProduct1() { 25 return new Product1(); 26 } 27 public IProduct2 createProduct2() { 28 return new Product2(); 29 } 30 } 31 32 public class Client { 33 public static void main(String[] args){ 34 IFactory factory = new Factory(); 35 factory.createProduct1().show(); 36 factory.createProduct2().show(); 37 } 38 }
抽象工厂模式的优势:
抽象工厂模式除了具备工厂方法模式的优势外,最主要的优势就是能够在类的内部对产品族进行约束。所谓的产品族,通常或多或少的都存在必定的关联,抽象工厂模式就能够在类内部对产品族的关联关系进行定义和描述,而没必要专门引入一个新的类来进行管理。
抽象工厂模式的缺点:
产品族的扩展将是一件十分费力的事情,假如产品族中须要增长一个新的产品,则几乎全部的工厂类都须要进行修改。因此使用抽象工厂模式时,对产品等级结构的划分是很是重要的。
适用场景:
当须要建立的对象是一系列相互关联或相互依赖的产品族时,即可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,若是存在着多个等级结构(即存在着多个抽象类),而且分属各个等级结构中的实现类之间存在着必定的关联或者约束,就可使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行建立,则更合适一点。
工厂模式要点:
1)简单工厂模式(静态工厂模式) 虽然某种程度不符合设计原则,但实际使用最多。
2)工厂方法模式 不修改已有类的前提下,经过增长新的工厂类实现扩展。
3)抽象工厂模式 不能够增长产品,能够增长产品族。
应用场景:
1)JDK中Calendar的getInstance方法;
2)JDBC中Connection对象的获取;
3)Hibernate中SessionFactory建立Session;
4)Spring中IOC容器建立管理bean对象;
5)XML解析时的DocumentBuilderFactory建立解析器对象;
6)反射中Class对象的newInstance()。