在初学设计模式【4】简单工厂模式——SimpleFactory中介绍了工厂模式中最简单的一个模式——简单工厂模式。正如它的名字一样,此模式的确很简单,但缺点也很明显。如果需要添加新的产品类时,就需要修改工厂类。很明显这违反了一个重要的OO设计原则——开闭原则。为了克服简单工厂模式的这个问题,就有了一个新的工厂模式——工厂方法模式。
定义
定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
UML类图
分析:1>Product与Creator都是抽象类,Creator中有一个抽象工厂方法factoryMethod,此方法也是此模式的核心。各具体创建者类必须实现此方法,以实现不同的子类。
2>核心工厂类如上图的Creator不再负责具体产品实例的创建,而仅仅是负责给出具体工厂子类必须实现的接口,让工厂子类去负责具体产品实例的创建。
3>因为此模式将实例化推迟到了子类中,所以如果我们想增加新产品,只需要重新写一个继承自抽象创建者类的具体创建者类,实现factoryMethod方法即可。除此之外不需要修改任何代码。严格遵守了“开闭原则”。
实例
例子uml图:
应该是很清楚的,就不多解释了。
代码
1>Phone
View Code
1 public abstract class Phone { 2 String name; 3 String IMEI; 4 String color; 5 String weight; 6 7 public Phone(String name) { 8 this.name = name; 9 } 10 11 public void dial() { 12 System.out.println(name + " is dialling"); 13 } 14 15 public void sendMessage() { 16 System.out.println(name + " is sending Message"); 17 } 18 19 public void phoneInfo() { 20 System.out.println("this phone info:" + toString()); 21 } 22 23 @Override 24 public String toString() { 25 return "Phone [name=" + name + ", IMEI=" + IMEI + ", color=" + color 26 + ", weight=" + weight + "]"; 27 } 28 29 }
2>MotoPhone,NokiaPhone
View Code
1 public class MotoPhone extends Phone { 2 3 public MotoPhone(String name) { 4 super(name); 5 } 6 7 } 8 9 10 public class NokiaPhone extends Phone { 11 12 public NokiaPhone(String name) { 13 super(name); 14 } 15 16 }
3>PhoneFactory
View Code
1 public abstract class PhoneFactory { 2 /** 3 * 工厂方法 4 * 5 * @return 具体种类的phone 6 */ 7 public abstract Phone factoryMethod(); 8 9 // 下面可以定义一些其它的方法,完成与产品相关的其它业务逻辑 10 public Phone createPhone() { 11 Phone phone = factoryMethod(); 12 System.out.println(phone.name + " is preparing"); 13 phone.IMEI = "fjieww892fjk3j292jfjjj933"; 14 phone.color = "Red"; 15 phone.weight = "120g"; 16 System.out.println(phone.name + " prepare finished"); 17 return phone; 18 } 19 }
4>MotoPhoneFactory,NokiaPhoneFactory
public class NokiaPhoneFactory extends PhoneFactory { @Override public Phone factoryMethod() { return new NokiaPhone("Nokia"); } } public class MotoPhoneFactory extends PhoneFactory { @Override public Phone factoryMethod() { return new MotoPhone("MotoRola"); } }
5>测试
View Code
1 import org.junit.Test; 2 3 public class Testt { 4 5 @Test 6 public void test() { 7 Phone phone = new MotoPhoneFactory().createPhone(); 8 phone.phoneInfo(); 9 phone.sendMessage(); 10 } 11 }
输出:
分析:
可以看到,如果我们想增加新的手机种类,比如Iphone,只需继承PhoneFactory写一个IphoneFactory重写里面的工厂方法,当然还要写一个Iphone的具体产品类。