創(chuàng)建型模式:關(guān)注如何創(chuàng)建對(duì)象。隱藏了類的實(shí)例的創(chuàng)建細(xì)節(jié),通過(guò)隱藏對(duì)象如何被創(chuàng)建和組合在一起達(dá)到使整個(gè)系統(tǒng)獨(dú)立的目的。(將不同的類分開(kāi)蝶桶,如果一個(gè)Computer內(nèi)的Printer想改為BetterPrinter,則需要修改Computer源碼掉冶。使Computer創(chuàng)建時(shí)真竖,傳入Printer類型,使分離厌小。開(kāi)閉原則恢共。)
工廠:建立實(shí)例時(shí),向工廠“輸入信息”璧亚。在工廠類中讨韭,選擇超類和多個(gè)子類之一實(shí)現(xiàn)。對(duì)象的實(shí)例創(chuàng)建由工廠代替new。
tips:超類可以是接口透硝、抽象類狰闪、父類。
解決問(wèn)題:接口選擇問(wèn)題濒生。
創(chuàng)建型模式(Creational Pattern)對(duì)類的實(shí)例化過(guò)程進(jìn)行了抽象埋泵,能夠?qū)④浖K中對(duì)象的創(chuàng)建和對(duì)象的使用分離。為了使軟件的結(jié)構(gòu)更加清晰甜攀,外界對(duì)于這些對(duì)象只需要知道它們共同的接口秋泄,而不清楚其具體的實(shí)現(xiàn)細(xì)節(jié)琐馆,使整個(gè)系統(tǒng)的設(shè)計(jì)更加符合單一職責(zé)原則规阀。
創(chuàng)建型模式在創(chuàng)建什么(What),由誰(shuí)創(chuàng)建(Who)瘦麸,何時(shí)創(chuàng)建(When)等方面都為軟件設(shè)計(jì)者提供了盡可能大的靈活性谁撼。
創(chuàng)建型模式隱藏了類的實(shí)例的創(chuàng)建細(xì)節(jié),通過(guò)隱藏對(duì)象如何被創(chuàng)建和組合在一起達(dá)到使整個(gè)系統(tǒng)獨(dú)立的目的滋饲。
一厉碟、介紹
二、實(shí)現(xiàn)
1.簡(jiǎn)單工廠模式(靜態(tài)工廠模式屠缭,違背開(kāi)閉原則箍鼓,抽象、具體的產(chǎn)品呵曹、具體工廠)
// 計(jì)算類的基類
public abstract class Operation {
private double value1 = 0;
private double value2 = 0;
public double getValue1() {
return value1;
}
public void setValue1(double value1) {
this.value1 = value1;
}
public double getValue2() {
return value2;
}
public void setValue2(double value2) {
this.value2 = value2;
}
protected abstract double getResule();
}
//加法
public class OperationAdd extends Operation {
@Override
protected double getResule() {
return getValue1() + getValue2();
}
}
//減法
public class OperationSub extends Operation {
@Override
protected double getResule() {
return getValue1() - getValue2();
}
}
//乘法
public class OperationMul extends Operation {
@Override
protected double getResule() {
return getValue1() * getValue2();
}
}
//除法
public class OperationDiv extends Operation {
@Override
protected double getResule() {
if (getValue2() != 0) {
return getValue1() / getValue2();
}
throw new IllegalArgumentException("除數(shù)不能為零");
}
}
//工廠類
public class OperationFactory {
public static Operation createOperation(String operation) {
Operation oper = null;
switch (operation) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
throw new UnsupportedOperationException("不支持該操作");
}
return oper;
}
}
//使用工廠類
Operation operationAdd = OperationFactory.createOperation("+");
operationAdd.setValue1(10);
operationAdd.setValue2(5);
System.out.println(operationAdd.getResule());
一個(gè)萬(wàn)能的大工廠款咖,可生產(chǎn)各種產(chǎn)品。如增加新產(chǎn)品奄喂,需要修改大工廠內(nèi)部代碼铐殃,不符合開(kāi)閉原則。
2.工廠方法模式(抽象跨新、具體的產(chǎn)品富腊、工廠)
工廠方法模式的實(shí)質(zhì)是“定義一個(gè)創(chuàng)建對(duì)象的接口,但讓實(shí)現(xiàn)這個(gè)接口的類來(lái)決定實(shí)例化哪個(gè)類域帐。工廠方法讓類的實(shí)例化推遲到子類中進(jìn)行赘被。”
工廠方法模式和簡(jiǎn)單工廠模式雖然都是通過(guò)工廠來(lái)創(chuàng)建對(duì)象肖揣,他們之間最大的不同是——工廠方法模式在設(shè)計(jì)上完全完全符合“開(kāi)閉原則”民假。
//將OperationFactory修改:
//工廠接口,抽象父類
public interface IFactory {
Operation CreateOption();
}
//加法類工廠
public class AddFactory implements IFactory {
public Operation CreateOption() {
return new OperationAdd();
}
}
//除法類工廠
public class DivFactory implements IFactory {
public Operation CreateOption() {
return new OperationDiv();
}
}
//除法類工廠
public class MulFactory implements IFactory {
public Operation CreateOption() {
return new OperationMul();
}
}
//減法類工廠
public class SubFactory implements IFactory {
public Operation CreateOption() {
return new OperationSub();
}
}
將萬(wàn)能的大工廠许饿,用抽象父類和每種產(chǎn)品對(duì)應(yīng)的一個(gè)工廠來(lái)替代阳欲,一個(gè)工廠負(fù)責(zé)一種產(chǎn)品。新產(chǎn)品,新建產(chǎn)品類后球化,新修一個(gè)工廠便是秽晚,不用修改原來(lái)的工廠內(nèi)部代碼,符合開(kāi)閉原則筒愚。
工廠方法模式又被稱為多態(tài)工廠模式赴蝇,是因?yàn)樗械木唧w工廠類都具有同一抽象父類。
工廠方法模式的主要優(yōu)點(diǎn)是增加新的產(chǎn)品類時(shí)無(wú)須修改現(xiàn)有系統(tǒng)巢掺,并封裝了產(chǎn)品對(duì)象的創(chuàng)建細(xì)節(jié)句伶,系統(tǒng)具有良好的靈活性和可擴(kuò)展性;其缺點(diǎn)在于增加新產(chǎn)品的同時(shí)需要增加新的工廠陆淀,導(dǎo)致系統(tǒng)類的個(gè)數(shù)成對(duì)增加考余,在一定程度上增加了系統(tǒng)的復(fù)雜性。
3.抽象工廠模式(抽象轧苫、具體的產(chǎn)品楚堤、工廠)根據(jù)不同的分類方式
開(kāi)閉原則傾斜性支持,傾斜于產(chǎn)品族含懊,而非單個(gè)產(chǎn)品(大種類)身冬。
提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無(wú)須指定它們具體的類岔乔。抽象工廠模式又稱為Kit模式酥筝,屬于對(duì)象創(chuàng)建型模式。
抽象工廠模式將同一產(chǎn)品族的單獨(dú)的工廠封裝起來(lái)雏门。使用中嘿歌,客戶端程序創(chuàng)建抽象工廠的具體實(shí)現(xiàn),使用抽象工廠作為接口來(lái)創(chuàng)建這一主題的具體對(duì)象剿配〗练客戶端程序不需要知道(或關(guān)心)它從這些內(nèi)部的工廠方法中獲得對(duì)象的具體類型,因?yàn)榭蛻舳顺绦騼H使用這些對(duì)象的通用接口呼胚。抽象工廠模式將一組對(duì)象的實(shí)現(xiàn)細(xì)節(jié)與他們的一般使用分離開(kāi)來(lái)茄唐。
抽象工廠模式的一個(gè)工廠可以創(chuàng)建屬于一類類型的多種具體產(chǎn)品。工廠創(chuàng)建產(chǎn)品的個(gè)數(shù)介于簡(jiǎn)單工廠模式和工廠方法模式之間蝇更。
//抽象產(chǎn)品
public interface BenzCar {
//加汽油
public void gasUp();
}
public interface TeslaCar {
//充電
public void charge();
}
//具體產(chǎn)品
public class BenzSportCar implements BenzCar {
public void gasUp() {
System.out.println("給我的奔馳跑車加最好的汽油");
}
}
public class BenzBusinessCar implements BenzCar{
public void gasUp() {
System.out.println("給我的奔馳商務(wù)車加一般的汽油");
}
}
public class TeslaSportCar implements TeslaCar {
public void charge() {
System.out.println("給我特斯拉跑車沖滿電");
}
}
public class TeslaBusinessCar implements TeslaCar {
public void charge() {
System.out.println("不用給我特斯拉商務(wù)車沖滿電");
}
}
//抽象工廠
public interface CarFactory {
public BenzCar getBenzCar();
public TeslaCar getTeslaCar();
}
//具體工廠
public class SportCarFactory implements CarFactory {
public BenzCar getBenzCar() {
return new BenzSportCar();
}
public TeslaCar getTeslaCar() {
return new TeslaSportCar();
}
}
public class BusinessCarFactory implements CarFactory {
public BenzCar getBenzCar() {
return new BenzBusinessCar();
}
public TeslaCar getTeslaCar() {
return new TeslaBusinessCar();
}
}
抽象工廠模式的主要優(yōu)點(diǎn)是隔離了具體類的生成沪编,使得客戶并不需要知道什么被創(chuàng)建,而且每次可以通過(guò)具體工廠類創(chuàng)建一個(gè)產(chǎn)品族中的多個(gè)對(duì)象年扩,增加或者替換產(chǎn)品族比較方便蚁廓,增加新的具體工廠和產(chǎn)品族很方便;主要缺點(diǎn)在于增加新的產(chǎn)品等級(jí)結(jié)構(gòu)(大種類)很復(fù)雜厨幻,需要修改抽象工廠和所有的具體工廠類相嵌,對(duì)“開(kāi)閉原則”的支持呈現(xiàn)傾斜性腿时。
4.實(shí)現(xiàn)對(duì)比
簡(jiǎn)單工廠模式:
1.抽象產(chǎn)品:所有產(chǎn)品的共性。
2.具體產(chǎn)品:新增時(shí)饭宾,新加產(chǎn)品類批糟。
3.具體工廠:大工廠,生產(chǎn)所有種類產(chǎn)品看铆。新增產(chǎn)品時(shí)徽鼎,需要對(duì)大工廠內(nèi)部代碼修改。
工廠方法模式:
1.抽象產(chǎn)品:所有產(chǎn)品共性弹惦。
2.具體產(chǎn)品:新增時(shí)否淤,新加產(chǎn)品類。
3.抽象工廠:所有工廠共性(如生產(chǎn)一個(gè)產(chǎn)品)棠隐。
4.具體工廠:每個(gè)產(chǎn)品對(duì)應(yīng)一個(gè)具體工廠石抡。新增時(shí),新增一個(gè)具體工廠便可宵荒。
抽象工廠模式:即根據(jù)產(chǎn)品的不同類型汁雷、分類方式
1.抽象產(chǎn)品:不同大種類净嘀。
2.具體產(chǎn)品:依據(jù)產(chǎn)品族报咳,將每個(gè)大種類分類為每種具體產(chǎn)品。
3.抽象工廠:不同大種類挖藏。
4.具體工廠:根據(jù)產(chǎn)品族創(chuàng)建暑刃,根據(jù)產(chǎn)品族,在內(nèi)部確定每個(gè)大種類對(duì)應(yīng)的產(chǎn)品族中的具體產(chǎn)品膜眠。增加產(chǎn)品族時(shí)岩臣,創(chuàng)建新的工廠。增加新產(chǎn)品時(shí)宵膨,抽象工廠和具體工廠都要修改架谎。
簡(jiǎn)單工廠 : 用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品。(對(duì)于增加新的產(chǎn)品辟躏,主要是新增產(chǎn)品谷扣,就要修改工廠類。符合單一職責(zé)原則捎琐。不符合開(kāi)放-封閉原則)
工廠方法 :用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的固定產(chǎn)品会涎。(支持增加任意產(chǎn)品,新增產(chǎn)品時(shí)不需要更改已有的工廠瑞凑,需要增加該產(chǎn)品對(duì)應(yīng)的工廠末秃。符合單一職責(zé)原則、符合開(kāi)放-封閉原則籽御。但是引入了復(fù)雜性)
抽象工廠 :用來(lái)生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品练慕。(增加新產(chǎn)品時(shí)惰匙,需要修改工廠,增加產(chǎn)品族時(shí)铃将,需要增加工廠徽曲。符合單一職責(zé)原則,部分符合開(kāi)放-封閉原則麸塞,降低了復(fù)雜性)