又一次看到了工廠模式,經過思考之後對工廠模式又有了新的認識。首先舉例說下使用工廠模式的好處:現在有一個繪畫的類(Print)裏面有一個方法print()需要調用RedPen裏面的write()方法,初學的時候是這樣寫的:
RedPen類:
public class RedPen {
public void write(){
System.out.println("use red color writing....");
}
}
Print類:
public class Print {
private RedPen pen;
public Print() {
super();
}
public Print(RedPen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
RedPen redPen=new RedPen();
Print print=new Print(redPen);
print.print();
}
}
這樣寫似乎沒有什麼問題,A類需要調用B類的方法,直接New一個B類實例然後調用實例的方法;但是當考慮到程序的變更和問題的擴展時,問題也就出現了,比如現在我使用藍色的筆(BluePen)來寫,對於上面的代碼,由於Print類裏面構造的時候直接使用了RedPen是的程序的耦合度最高(硬編碼耦合),所以當需要修改的時候,要重新修改Print的構造方法改成:
public Print(BluePen pen),但是如果Print依賴的類跟多的話(例如還有畫刷,形狀等)都採用上述方式的話,當程序需要對功能有所調整的時候需要修改的地方會更多,因此我們需要使用接口:
還是以上述例子,我們如果增加一個Pen的接口,Print類依賴於Pen,有一個用來生產Pen的工廠(PenFactory)擴展之後如下圖:
因此Print的代碼改爲:
public class Print {
private Pen pen;
public Print() {
super();
}
public Print(Pen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
PenFactory factory=new PenFactory();
Print print=new Print(factory.getPen("blue"));
print.print();
}
}
工廠類:
public class PenFactory {
public Pen getPen(String color){
if("red".equals(color))
return new RedPen();
else
return new BluePen();
}
}
顯然經過重新設計之後,如果需要改成使用BluePen則只需要修改getPen()的參數即可,也就避免了對Print類作大量修改,這就就簡單工廠模式,在簡單工廠模式創建產品的方法中,根據傳入的參數來判斷到底創建哪個產品,如果不需要做判斷的話則可以改成工廠模式:
修改之後Print類的代碼改成:
public class Print {
private Pen pen;
public Print() {
super();
}
public Print(Pen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
PenFactory factory=new RedPenFactory();
Print print=new Print(factory.getPen());
print.print();
}
}
到此爲止我們已經實現了客戶端代碼(Print)與需要調用類的代碼分離,但是Print卻與具體的工廠類耦合起來,因此爲了進一步達到解耦效果,則可以使用抽象工廠方法:
只需要在上面的基礎上增加一個生產工廠的類:
自此就完成了Print與工廠類的完全解耦,在PenFactoryFactory的getPenFactory裏面需要根據不同的參數返回不同的工廠實例。其實不管是簡單工程模式還是抽象工廠模式都是工廠模式,不過是在不同的類裏面判斷而已,如果是直接返回被調用的對象,只是簡單工廠;如果是返回的工廠對象,則是抽象工廠。