1. 程式人生 > >工廠模式與靜態工廠

工廠模式與靜態工廠

1、工廠方法模式:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工廠方法使一個類的例項化延遲到其子類。

核心工廠類不再負責產品的建立,這樣核心類成為一個抽象工廠角色,僅負責具體工廠子類必須實現的介面,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。

2、工廠方法模式由4種角色組成:
(1)抽象工廠(Creator)角色:是工廠方法模式的核心,與應用程式無關。任何在模式中建立的物件的工廠類必須實現這個介面。
(2)具體工廠(Concrete Creator)角色:這是實現抽象工廠介面的具體工廠類,包含與應用程式密切相關的邏輯,並且受到應用程式呼叫以建立產品物件。

(3)抽象產品(Product)角色:工廠方法模式所建立的物件的超型別,也就是產品物件的共同父類或共同擁有的介面。
(4)具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所定義的介面。某具體產品有專門的具體工廠建立,它們之間往往一一對應。

3、工廠方法模式的UML類圖

4、工廠方法和簡單工廠的區別  
   工廠方法模式把簡單工廠的內部邏輯判斷移到了客戶端程式碼來進行。
   工廠方法模式是簡單工廠模式的衍生,首先完全實現開放-封閉原則,實現了可擴充套件。其次更復雜的層次結構,可以應用於產品結果複雜的場合。

5、下面實現一個加減乘除的工廠方法模式


package demo8;  
/** 
 * 工廠介面 
 * 
 */  
interface IFactory {  
    Operation CreateOperation();  
}  
  
  
package demo8;  
/** 
 * 具體工廠(Concrete Creator)角色:加法類工廠 
 * 
 */  
public class AddFactory implements IFactory {  
    @Override  
    public Operation CreateOperation() {  
        return new OperationAdd();  
    }     
}  
  
  
package demo8;  
/** 
 * 具體工廠(Concrete Creator)角色:減法類工廠 
 * 
 */  
public class SubFactory implements IFactory {  
    @Override  
    public Operation CreateOperation() {          
        return new OperationSub();  
    }  
}  
  
  
package demo8;  
/** 
 * 具體工廠(Concrete Creator)角色:乘法類工廠 
 * 
 */  
public class MulFactory implements IFactory {  
    @Override  
    public Operation CreateOperation() {          
        return new OperationMul();  
    }  
}  
  
  
package demo8;  
/** 
 * 具體工廠(Concrete Creator)角色:除法類工廠 
 * 
 */  
public class DivFactory implements IFactory {  
    @Override  
    public Operation CreateOperation() {          
        return new OperationDiv();  
    }  
}  
  
  
package demo8;  
/** 
 * 抽象產品(Product)角色:運算類 
 * 
 */  
public abstract class Operation {  
    private double numberA = 0;  
    private double numberB = 0;  
  
    public void setNumberA(double numberA) {  
        this.numberA = numberA;  
    }  
    public void setNumberB(double numberB) {  
        this.numberB = numberB;  
    }  
    public double getNumberA() {  
        return numberA;  
    }  
    public double getNumberB() {  
        return numberB;  
    }  
    public double getResult() {  
        double result = 0;  
        return result;  
    }     
}  
  
  
package demo8;  
/** 
 * 具體產品(Concrete Product)角色:加法類 
 * 
 */  
public class OperationAdd extends Operation {     
    @Override  
    public double getResult() {  
        double result = 0;  
        result = super.getNumberA() + super.getNumberB();  
        return result;  
    }  
}  
  
  
package demo8;  
/** 
 * 具體產品(Concrete Product)角色:減法類 
 * 
 */  
public class OperationSub extends Operation {     
    @Override  
    public double getResult() {  
        double result = 0;  
        result = super.getNumberA() - super.getNumberB();  
        return result;  
    }  
}  
  
  
package demo8;  
/** 
 * 具體產品(Concrete Product)角色:乘法類 
 * 
 */  
public class OperationMul extends Operation {  
    @Override  
    public double getResult() {  
        double result = 0;  
        result = super.getNumberA() * super.getNumberB();  
        return result;  
    }  
}  
  
  
package demo8;  
/** 
 * 具體產品(Concrete Product)角色:除法類 
 * 
 */  
public class OperationDiv extends Operation {  
    @Override  
    public double getResult() {  
        double result = 0;  
        if (super.getNumberB() == 0)              
            throw new ArithmeticException("除數不能為0.");             
        result = super.getNumberA() / super.getNumberB();  
        return result;  
    }  
}  
  
  
package demo8;  
/** 
 * 客戶端 
 * 
 */  
public class Demo8 {  
    public static void main(String[] args) {  
        IFactory operFactory = new AddFactory();          
        Operation oper = operFactory.CreateOperation();  
        oper.setNumberA(10);  
        oper.setNumberB(7);  
        double result = oper.getResult();  
        System.out.println(result);  
    }  
} 

靜態工廠:不通過 new,而是用一個靜態方法來對外提供自身例項的方法,即為我們所說的靜態工廠方法(Static factory method)

優勢

1,在有多個過載的建構函式,名字有區分度

2,有時候外部呼叫者只需要拿到一個例項,而不關心是否是新的例項;又或者我們想對外提供一個單例時 —— 如果使用工廠方法,就可以很容易的在內部控制,防止建立不必要的物件,減少開銷。

3,構造方法只能返回確切的自身型別,而靜態工廠方法則能夠更加靈活,可以根據需要方便地返回任何它的子型別的例項。