简单工厂模式:
简单工厂类:内有一个产品抽象类型的成员变量,控制着生产具体产品的逻辑(switch-case语句)
产品的抽象类:
具体的产品类:继承或实现了产品的抽象类(接口)。
举例来说,有生产手机(产品的抽象类)的工厂(简单工厂),工厂需要根据(相关负责人)传来的命令来决定是生产小米手机还是苹果手机(这个工厂有点像富士康)。这个小米手机和苹果手机就是手机的具体类。关于UML图示:
程序如下:
1 package com.dp.factory.simpleFactory; 2 3 //产品的抽象类 4 public abstract class Phone { 5 public abstract void printName(); 6 } 7 8 //具体的产品1 9 package com.dp.factory.simpleFactory; 10 11 public class ApplePhone extends Phone{ 12 13 @Override 14 public void printName() { 15 System.out.println("我是苹果!"); 16 } 17 } 18 19 //具体的产品2 20 package com.dp.factory.simpleFactory; 21 22 public class XiaomiPhone extends Phone{ 23 24 @Override 25 public void printName() { 26 System.out.println("我是小米!"); 27 } 28 29 } 30 31 //工厂类 32 package com.dp.factory.simpleFactory; 33 34 public class PhoneFactory { 35 36 public static Phone createPhone(String name){ 37 Phone p = null; 38 switch(name){ 39 case "Xiaomi" : p = new XiaomiPhone();break; 40 case "Apple" : p = new XiaomiPhone();break; 41 } 42 return p; 43 } 44 } 45 46 //测试类 47 package com.dp.factory.simpleFactory; 48 49 public class Test { 50 51 public static void main(String[] args) { 52 Phone p = null; 53 54 p = PhoneFactory.createPhone("Xiaomi"); 55 p.printName(); 56 } 57 } 58 59 //输出结果 60 我是小米!
工厂方法模式:
与简单工厂相比多了工厂类的抽象,工厂类不再有控制有生产具体产品的逻辑(switch-case),根据需要的产品选择对应的具体的工厂。
在简单工厂里增加判断逻辑,不利于程序的维护下,扩展性,比如,要加一个生产华为手机的选择,只能修改简单工厂类的实现。此时,对简单工厂类进行修改,
UML示意图:
示例程序如下:
在简单工厂的基础上对进行修改,将工厂单独抽象一个类,增加生产小米手机,苹果手机的继承自抽象工厂的类,
//工厂抽象类 package com.dp.factory.simpleFactory; public abstract class PhoneFactory { public abstract Phone createPhone(); } //Apple工厂 package com.dp.factory.simpleFactory; public class AppleFactory extends PhoneFactory{ @Override public Phone createPhone() { return new ApplePhone(); } } //小米工厂 package com.dp.factory.simpleFactory; public class XiaomiFactory extends PhoneFactory{ @Override public Phone createPhone() { return new XiaomiPhone(); } } //测试类 package com.dp.factory.simpleFactory; public class Test { public static void main(String[] args) { Phone p = null; PhoneFactory pf = new AppleFactory(); p = pf.createPhone(); p.printName(); } } //输出结果 我是苹果!
抽象工厂模式:
相比工厂方法模式,产品多了系列的概念。当一个工厂不是生产一类产品而是生产一系列产品(比如小米工厂生产手机,电视等等)的时候,再使用工厂方法模式,会造成类泛滥的后果(要有生产小米手机的工厂类,生产电视的类,因为手机电视都是一个厂的,我们就会考虑把它们合并起来,不然会写很多的类,就跟要建很多个厂一样)。
UML示意图:
示例程序:
//工厂抽象类 package com.dp.factory.simpleFactory; public abstract class AbstractFactory { public abstract Phone createPhone(); public abstract TV createTV(); } //Apple工厂 package com.dp.factory.simpleFactory; public class AppleFactory extends AbstractFactory{ @Override public Phone createPhone() { return new ApplePhone(); } @Override public TV createTV() { return new AppleTV(); } } //小米工厂 package com.dp.factory.simpleFactory; public class XiaomiFactory extends AbstractFactory{ @Override public Phone createPhone() { return new XiaomiPhone(); } @Override public TV createTV() { return new XiaomiTV(); } } package com.dp.factory.simpleFactory; public class AppleTV extends TV { @Override public void printName() { System.out.println("我是苹果电视"); } } package com.dp.factory.simpleFactory; public class XiaomiTV extends TV{ @Override public void printName() { System.out.println("我是小米电视"); } } //TV抽象类 package com.dp.factory.simpleFactory; public abstract class TV { public abstract void printName(); } //测试类 package com.dp.factory.simpleFactory; public class Test { public static void main(String[] args) { Phone p = null; TV t = null; AbstractFactory pf = new AppleFactory(); p = pf.createPhone(); t = pf.createTV(); p.printName(); t.printName(); } } //输出结果 我是苹果! 我是苹果电视
工厂方法模式可以看成系列产品只用一种的抽象工厂模式。
三种模式的比较:
简单工厂模式:
优点:共产类中包括了必要的逻辑判断,根据客户端的选择动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
缺点:可扩展性差,比如新增加一个产品,如手表,此时需要修改工厂的逻辑,增加一个case分支。
工厂方法模式:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。还可以理解厂,本来在工厂方法里判断生产何种产品的逻辑,通过增加工厂子类的方式去除了。
抽象工厂模式:
提供一个创建一系列相关或相互依赖的接口,而无需指定他们具体的类。
优点:
1.易于交换产品系列,由于具体工厂在一个应用中只需要在初始化时出现一次,这使得改变一个应用的具体工厂变得非常容易。只需根据自己的选择更换工厂就行。
2.具体的创建实例过程和客户端分离,客户端是通过它们的抽象类操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现客户端代码中。
缺点:
在一个产品系列中增加一类新的产品,比如增加一个手表,此时需要改动的类较多,有所有的工厂,增加所有手表类。