簡(jiǎn)單工廠模式(補(bǔ)充)
也稱為靜態(tài)工廠方法模式,由一個(gè)工廠對(duì)象決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例。
簡(jiǎn)單工廠模式中有如下角色:
- 工廠類:核心,負(fù)責(zé)創(chuàng)建所有實(shí)例的內(nèi)部邏輯,由外界直接調(diào)用。
- 抽象產(chǎn)品類:要?jiǎng)?chuàng)建所有對(duì)象的抽象父類,負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
- 具體產(chǎn)品類:要?jiǎng)?chuàng)建的產(chǎn)品。
簡(jiǎn)單示例
1、抽象產(chǎn)品類
public abstract class MobilePhone {
public abstract String brand();
}
2、具體產(chǎn)品類
public class XiaoMiMobilePhone extends MobilePhone {
@Override
public String brand() {
return "xiaomi";
}
}
public class HuaWeiMobilePhone extends MobilePhone {
@Override
public String brand() {
return "huawei";
}
}
public class VivoMobilePhone extends MobilePhone {
@Override
public String brand() {
return "vivo";
}
}
3、工廠類
public class MobilePhoneFactory {
public static MobilePhone createMobilePhone(String type) {
MobilePhone mobilePhone = null;
switch (type) {
case "xiaomi":
mobilePhone = new XiaoMiMobilePhone();
break;
case "huawei":
mobilePhone = new HuaWeiMobilePhone();
break;
case "vivo":
mobilePhone = new VivoMobilePhone();
break;
}
return mobilePhone;
}
}
測(cè)試
@Test
public void testSimpleFactory() {
System.out.println("xiaomi:"+ MobilePhoneFactory.createMobilePhone("xiaomi").brand());
System.out.println("huawei:"+ MobilePhoneFactory.createMobilePhone("huawei").brand());
System.out.println("vivo:"+ MobilePhoneFactory.createMobilePhone("vivo").brand());
}
測(cè)試結(jié)果
xiaomi:xiaomi
huawei:huawei
vivo:vivo
它需要知道所有工廠類型,因此只適合工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少的情況。
避免直接實(shí)例化類,降低耦合性。
增加新產(chǎn)品需要修改工廠,違背開放封閉原則。
工廠方法模式
定義一個(gè)用于創(chuàng)建對(duì)象的接口,使類的實(shí)例化延遲到子類。
工廠方法有以下角色:
- 抽象產(chǎn)品類。
- 具體產(chǎn)品類。
- 抽象工廠類:返回一個(gè)泛型的產(chǎn)品對(duì)象。
- 具體工廠類:返回具體的產(chǎn)品對(duì)象。
簡(jiǎn)單示例
抽象產(chǎn)品類和具體產(chǎn)品類同簡(jiǎn)單工廠一樣。
1、抽象工廠類
public abstract class AbstractMobilePhoneFactory {
public abstract <T extends MobilePhone> T createMobilePhone(Class<T> clz);
}
4、具體工廠類
public class MobilePhoneFactoryImpl extends AbstractMobilePhoneFactory {
@Override
public <T extends MobilePhone> T createMobilePhone(Class<T> clz) {
MobilePhone mobilePhone = null;
String classname = clz.getName();
try {
mobilePhone = (MobilePhone) Class.forName(classname).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) mobilePhone;
}
}
獲取工廠實(shí)例單例
//第一次調(diào)用getInstance方法時(shí)虛擬機(jī)才加載SingletonHolder并初始化sInstance,這樣保證了線程安全和實(shí)例的唯一性。
public class MobilePhoneFactoryImplSingleton {
private MobilePhoneFactoryImplSingleton() {
}
public static MobilePhoneFactoryImpl getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final MobilePhoneFactoryImpl sInstance = new MobilePhoneFactoryImpl();
}
}
@Test
public void testAbstractFactory() {
System.out.println("instance1:"+ MobilePhoneFactoryImplSingleton.getInstance());
System.out.println("instance2:"+ MobilePhoneFactoryImplSingleton.getInstance());
System.out.println("vivo:"+ MobilePhoneFactoryImplSingleton.getInstance().createMobilePhone(VivoMobilePhone.class).brand());
System.out.println("huawei:"+MobilePhoneFactoryImplSingleton.getInstance().createMobilePhone(HuaWeiMobilePhone.class).brand());
System.out.println("xiaomi:"+ MobilePhoneFactoryImplSingleton.getInstance().createMobilePhone(XiaoMiMobilePhone.class).brand());
}
測(cè)試結(jié)果
instance1:sysshare.lq.com.demosapplication.designPattern.factory.abstractFactory.MobilePhoneFactoryImpl@2957fcb0
instance2:sysshare.lq.com.demosapplication.designPattern.factory.abstractFactory.MobilePhoneFactoryImpl@2957fcb0
vivo:vivo
huawei:huawei
xiaomi:xiaomi
- 相比簡(jiǎn)單工廠,如果我們需要新增產(chǎn)品類,無(wú)需修改工廠類,直接創(chuàng)建產(chǎn)品即可。