工廠方法設(shè)計模式
工廠方法設(shè)計模式的定義
1.定義:定義一個用于創(chuàng)建對象的接口兔港,讓子類決定實例化哪一個類.工廠方法使一個類的實例化延遲到其子類
工廠方法設(shè)計模式結(jié)構(gòu)圖
image.png
工廠方法設(shè)計模式的具體實現(xiàn)
代碼結(jié)構(gòu):
image.png
調(diào)用關(guān)系:
image.png
1.新建一個定義工廠方法所創(chuàng)建的抽象對象或接口
package org.example.factory;
/**
* @author yangzhenhua
* @date 2021/3/15 16:11
**/
package org.example.factory;
/**
* @author
* @date 2021/3/15 16:11
**/
public abstract class Operation {
private Double numberA;
private Double numberB;
public abstract Double getResult();
public Double getNumberA() {
return numberA;
}
public void setNumberA(Double numberA) {
this.numberA = numberA;
}
public Double getNumberB() {
return numberB;
}
public void setNumberB(Double numberB) {
this.numberB = numberB;
}
}
2.創(chuàng)建一個工廠方法,該方法返回抽象對象
package org.example.factory;
/**
* @author
* @date 2021/3/15 16:15
**/
public interface OperationFactory {
Operation createOperation();
}
3.新建具體的操作對象
public class OperationAdd extends Operation {
@Override
public Double getResult() {
return this.getNumberA()+this.getNumberB();
}
}
public class OperationSub extends Operation {
@Override
public Double getResult() {
return this.getNumberA()-this.getNumberB();
}
}
public class OperationMul extends Operation{
@Override
public Double getResult() {
return this.getNumberA()*this.getNumberB();
}
}
public class OperationDiv extends Operation{
@Override
public Double getResult() {
if (this.getNumberB()==0){
throw new RuntimeException();
}
return this.getNumberA()/this.getNumberB();
}
}
4.新建具體的工廠對象對應(yīng)具體的操作對象
public class OperationAddFactory implements OperationFactory{
@Override
public Operation createOperation() {
return new OperationAdd();
}
}
public class OperationSub extends Operation {
@Override
public Double getResult() {
return this.getNumberA()-this.getNumberB();
}
}
public class OperationMulFactory implements OperationFactory {
@Override
public Operation createOperation() {
return new OperationMul();
}
}
public class OperationDivFactory implements OperationFactory {
@Override
public Operation createOperation() {
return new OperationDiv();
}
}
5.客戶端調(diào)用
public class Test {
public static void main(String[] args) {
OperationFactory operationFactory = new OperationAddFactory();
Operation operation = operationFactory.createOperation();
operation.setNumberA(1.2);
operation.setNumberB(1.2);
Double result = operation.getResult();
System.out.println("result:"+result);
}
}
6.運行結(jié)果
image.png
工廠方法模式的優(yōu)缺點
優(yōu)點
1.更符合開閉原則:新增一種產(chǎn)品時只需要新增具體的產(chǎn)品和產(chǎn)品工廠即可
2.符合單一職責(zé)原則:每個工廠類只負責(zé)創(chuàng)建對應(yīng)的產(chǎn)品
3.不適用靜態(tài)方法可以形成基于繼承的等級結(jié)構(gòu)
總結(jié):工廠方法模式可以說是簡單工廠模式的進一步總結(jié)和拓展,在保留簡單工廠封裝優(yōu)點的同時,讓擴展變得簡單,讓繼承變得可行,增加了多態(tài)性的體現(xiàn)
缺點
1.添加新產(chǎn)品時除了新增產(chǎn)品類外,還需新增產(chǎn)品工廠,系統(tǒng)類的個數(shù)將相對增加,在一定程度上增加了系統(tǒng)的復(fù)雜性,同時有更多的類需要編譯和運行,會給系統(tǒng)帶來額外的開銷
2.由于考慮到系統(tǒng)的可拓展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統(tǒng)的抽象性和理解難度,且在實現(xiàn)時需要考慮多種技術(shù),增加了系統(tǒng)的實現(xiàn)難度;