今天和大家分享一下設(shè)計(jì)模式中的 簡(jiǎn)單工廠 工廠方法 抽象工廠
上圖是工廠模式百度百科的截圖,工廠模式(三種模式)的目的在于程序的可擴(kuò)展性忿薇,便于維護(hù)堤瘤,減少開發(fā)出錯(cuò),本人總結(jié)為工廠模式就是讓類的創(chuàng)建和使用分離狭魂,降低程序模塊之間的耦合程度(歡迎提出質(zhì)疑)
1.簡(jiǎn)單工廠模式(Simple Factory Pattern)
我這里來拿《大話設(shè)計(jì)模式》中“大鳥”指導(dǎo)“小菜”完成的一個(gè)簡(jiǎn)單工廠來舉例子(編寫一個(gè)簡(jiǎn)單的計(jì)算器程序)猖闪,這里我把他的c#代碼換成了本人學(xué)習(xí)的java -- ps:本人也是剛畢業(yè)不久的菜鳥一枚吹榴,正在看這本書就當(dāng)是寫個(gè)個(gè)人總結(jié)和大家分享一下。這本書評(píng)價(jià)不錯(cuò)京東有正版有能力的朋友可以支持一下作者畏吓。也可以看網(wǎng)絡(luò)上的pdf.....
首先來分析一下計(jì)算器程序的目的是為了得到一個(gè)計(jì)算結(jié)果墨状,我們應(yīng)該抽象出這個(gè)結(jié)果首先我們是我們的抽象接口代碼
public interface Operation {
public double getResult(double number_a,double number_b);
}
Operation 接口中一個(gè)getResult 參數(shù)為 兩個(gè)double數(shù)。
假設(shè)目前只要滿足 + - * /的計(jì)算 好了我們來新建四個(gè)計(jì)算的運(yùn)算類分別實(shí)現(xiàn)接口Operation
public class OperationAdd implements Operation{
@Override
public double getResult(double number_a, double number_b) {
double result=0;
result= number_a+number_b;
return result;
}
}
public class OperationMul implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
result=number_a*number_b;
return result;
}
}
public class OperationSub implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
result= number_a-number_b;
return result;
}
}
public class OperationDiv implements Operation{
@Override
public double getResult(double number_a,double number_b) {
double result=0;
if(number_b==0)
{
try {
throw new Exception("除數(shù)不能為零");
} catch (Exception e) {
e.printStackTrace();
}
}
result=number_a/number_b;
return result;
}
}
這里大家是不是萬事具備只欠東風(fēng)了呢菲饼,問題來了具體的運(yùn)算類怎么調(diào)用 何時(shí)調(diào)用誰呢肾砂,這時(shí)間我們把我們的重點(diǎn)工廠類請(qǐng)出來了,讓它決定我們?cè)趺词褂镁唧w的運(yùn)算類
public class OperationFactory {
private static OperationFactory instance ;
private OperationFactory(){}
public static OperationFactory getInstance(){
if (instance == null) {
synchronized (OperationFactory.class){
if (instance == null) {
instance = new OperationFactory();
}
}
}
return instance ;
}
public Operation createOperation(String operator){
Operation operation=null;
switch (operator)
{
case "+":
operation=new OperationAdd();
break;
case "-":
operation=new OperationSub();
break;
case "*":
operation=new OperationMul();
break;
case "/":
operation=new OperationDiv();
break;
default:
try {
throw new Exception("請(qǐng)輸入正確的運(yùn)算符");
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return operation;
}
public Operation makeOperation(Class c)
{
Operation operation=null;
try {
operation=(Operation) Class.forName(c.getName()).newInstance();
}catch (InstantiationException e) {
System.out.println("不支持抽象類或接口");
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
System.out.println("沒有足夠權(quán)限宏悦,即不能訪問私有對(duì)象");
} catch (ClassNotFoundException e) {
System.out.println("類不存在");
e.printStackTrace();
} catch (ClassCastException e)
{
System.out.println("選擇的類不正確");
}
return operation;
}
}
我們先不管makeOperation方法先看createOperation方法通今。
createOperation只需要在調(diào)用的時(shí)間接受operator參數(shù)(+-*/)就能返回所對(duì)應(yīng)的運(yùn)算類了
下面是客戶端代碼
public class Main {
public static void main(String[] args) {
Operation operation;
operation=OperationFactory.getInstance().createOperation("+");
System.out.println(operation.getResult(1,1));
}
}
不用我說輸出結(jié)果為2
這里我們利用java的多態(tài)性調(diào)用了OperationAdd 類的getResult方法傳入了1 和1
但是怎么創(chuàng)建的OperationAdd 我們并沒有去管粥谬。這就是簡(jiǎn)單工廠的一個(gè)實(shí)例了
也許大家會(huì)認(rèn)為這么設(shè)計(jì)出來的計(jì)算器程序應(yīng)該很完美了吧,然而并不是辫塌。
沒有遵守開放—封閉原則漏策。所謂的“開放-封閉”原則就是開放接口,封閉修改臼氨。如果將來需要添加一個(gè)開方的算法掺喻,那么,在簡(jiǎn)單工廠模式中储矩,就必須在簡(jiǎn)單工廠類中添加相應(yīng)的判斷語句感耙。前面說的必須也不是那么絕對(duì),這時(shí)我們?cè)倏垂S類中的makeOperation 方法 如果要加入一個(gè)開方的運(yùn)算類持隧,我們不改工廠類的邏輯是可以通過newInstance調(diào)用這個(gè)新的開方運(yùn)算律但是 newInstance是弱類型即硼。所以想完全的按照開放—封閉原則我們還是要來看一下工廠方法模式
優(yōu)點(diǎn)
簡(jiǎn)單工廠顧名思義就是你只管調(diào)用操作不需要管創(chuàng)建類的過程所以叫簡(jiǎn)單工廠(根據(jù)客戶端的選擇條件動(dòng)態(tài)實(shí)例化相關(guān)的類,對(duì)客戶端調(diào)用來說除去了與具體產(chǎn)品的依賴)因?yàn)閯?chuàng)建的邏輯交給了工廠類,相當(dāng)于就是給類的創(chuàng)建做了封裝屡拨。
缺點(diǎn)
簡(jiǎn)單工廠沒有遵守開放—封閉原則只酥。所謂的“開放-封閉”原則就是開放接口,封閉修改呀狼。如果將來需要添加一個(gè)開方的算法裂允,那么,在簡(jiǎn)單工廠模式中哥艇,就必須在簡(jiǎn)單工廠類中添加相應(yīng)的case語句绝编!
2. 工廠方法模式
晚上更新
3. 抽象工廠模式
晚上更新