设计模式:抽象工厂模式
工厂方法有两个缺点,一是如果要增加一个产品的话,虽然原来的已有代码不需要改动,但是要成对地增加类。一个产品对应一个工厂。再者就是如果有些产品是要在一起出现的话,管理起来容易出错。比如说界面UI。打个比方,假如每套UI包含两个样式,一个是标题样式,一个是正文样式。如果有两套UI,那么就有4个具体工厂和4个具体产品,如果想要更换UI,就得获取对应的两个产品(标题样式和正文样式)。如果需求改动,要增加更多的UI,那么工厂方法模式或许不是一种好方法。
抽象工厂模式弥补了工厂方法模式的这两个缺点。抽象工厂模式里面一个抽象工厂生产多个产品。比如说一个网站,站长开发了多套UI供用户使用。用户用多套UI里面选择自己喜欢的UI。每套UI都包括标题样式和正文样式。那么UI抽象工厂里面有两个抽象的工厂方法,一个方法生产一种产品。
以下的例子基于一个产业只生产两种产品,手机和电视。有两个厂商,HuaWei
和ZTE
。
目录结构如下:
| | |-Client.java
| | |-Factory.java
| | |-factory.properties
| | |-HuaWeiFactory.java
| | |-HuaWeiPhone.java
| | |-HuaWeiTV.java
| | |-Phone.java
| | |-PropertyUtil.java
| | |-TV.java
| | |-ZTEFactory.java
| | |-ZTEPhone.java
| | `-ZTETV.java
Factory.java
抽像工厂类
public interface Factory{
Phone createPhone();//工厂方法,生产手机
TV createTV();//工厂方法,生产电视
}
HuaWei具体工厂类HuaWeiFactory.java
public class HuaWeiFactory implements Factory{
public Phone createPhone(){
HuaWeiPhone phone = new HuaWeiPhone();
return phone;
}
public TV createTV(){
HuaWeiTV tv = new HuaWeiTV();
return tv;
}
}
手机抽象类Phone.java
public interface Phone{
public void display();
}
HuaWei手机具体类HuaWeiPhone.java
public class HuaWeiPhone implements Phone{
public void display(){
System.out.println("HuaWeiPhone");
}
}
电视抽象类TV.java
public interface TV{
public void display();
}
HuaWei电视具体类HuaWeiTV.java
public class HuaWeiTV implements TV{
public void display(){
System.out.println("HuaWeiTV");
}
}
工厂配置文件factory.properties
className=HuaWeiFactory
配置文件工具类PropertyUtil.java
import java.io.*;
import java.util.*;
public class PropertyUtil{
public static Object getBean(){
Object obj = null;
try{
Properties prop = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream("factory.properties"));
prop.load(in);
String className = prop.getProperty("className");
Class c = Class.forName(className);
obj = c.newInstance();
}catch(Exception e){
//Exception
e.printStackTrace();
}
return obj;
}
}
客户端代码Client.java
public class Client{
public static void main(String args[]){
Factory factory = (Factory)PropertyUtil.getBean();
Phone phone = factory.createPhone();
TV tv = factory.createTV();
phone.display();
tv.display();
}
}
抽像工厂模式如果要增加厂商的话,那就很方便。但是如果要增加某一种产品的话,就得修加已有和各个类中的代码。抽象工厂模式比较适合那种固定产品类型的场景。
上面的例子中,如果要增加一个厂商ZTE
的话很方便。
ZTE手机具体产品类ZTEPhone.java
public class ZTEPhone implements Phone{
public void display(){
System.out.println("ZTEPhone");
}
}
ZTE电视具体产品类ZTETV.java
public class ZTETV implements TV{
public void display(){
System.out.println("ZTETV");
}
}
ZTE具体工厂类ZTEFactory.java
public class ZTEFactory implements Factory{
public Phone createPhone(){
ZTEPhone phone = new ZTEPhone();
return phone;
}
public TV createTV(){
ZTETV tv = new ZTETV();
return tv;
}
}
(完)