工廠方法模式分為四種:
- 普通工廠模式
- 多個工廠方法模式
- 靜态工廠方法模式
-
抽象工廠模式
下面一個個看
普通工廠模式
其實很簡單,先來看代碼,再來總結定義,舉例如下:(我們舉一個發送郵件和短信的例子)
//首先,建立二者的共同接口:
public interface Sender {
public void Send();
}
//其次,建立實作類,郵件發送類實作發送接口:
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
//建立實作類,短信發送類實作發送接口:
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
//最後,建工廠類:
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("請輸入正确的類型!");
return null;
}
}
}
//最後來測試一下
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.Send();
}
}
輸出如下:
this is sms sender!
到這裡就是普通工廠模式全部實作代碼,可以給出工廠模式的定義(個人了解,非标準定義)所謂普通工廠模式就是建立一個工廠類,對實作了同一接口的一些類進行管理,統一到用同一個工廠類中方法完成不同執行個體的建立
多個工廠方法模式
同樣的,先看代碼再總結:
上面的代碼大部分不用動,改動下SendFactory類就行:
public class SendFactory {
//為郵件發送類定義單獨建立方法
public Sender produceMail(){
return new MailSender();
}
//為短信發送類定義單獨建立方法
public Sender produceSms(){
return new SmsSender();
}
}
//測試類如下:
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.Send();
}
}
輸出如下:
this is mailsender!
多個工廠方法模式,就是對普通工廠方法模式的改進,将建立執行個體的方法從參數傳遞改進成為每個執行個體在工廠類中定義專門的方法,個人了解就像為每個産品建立一個專門的生産線,感覺效率和使用會比普通工廠類友善很多,但是每次使用都要new 個工廠對象,能不簡單點(簡單點~說話的方式簡單點~咳咳,回歸正題),答案是肯定的,那就要用到靜态工廠方法模式
靜态工廠方法模式
先上代碼(話說代碼是誰?!!捂臉)
public class SendFactory {
//注意這是個靜态方法
public static Sender produceMail(){
return new MailSender();
}
//注意這也是個靜态方法
public static Sender produceSms(){
return new SmsSender();
}
}
//測試類如下:
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
輸出結果:
this is mailsender!
總體來說,工廠模式适合:凡是出現了大量的産品需要建立,并且具有共同的接口時,可以通過工廠方法模式進行建立。
在以上的三種模式中,第一種如果傳入的字元串有誤,不能正确建立對象,第三種相對于第二種,不需要執行個體化工廠類,是以,大多數情況下,我們會選用第三種——靜态工廠方法模式
但是這樣就真的完美了嗎?仔細想想還有問題,類的建立依賴工廠類,也就是說,如果想要拓展程式,必須對工廠類進行修改,但這違背了閉包原則(就是說對擴充開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的代碼,實作一個熱插拔的效果。),是以,從設計角度考慮,有一定的問題,如何解決?就要用到抽象工廠模式
抽象工廠模式
老規矩,上代碼先( ̄_, ̄ ):
//首先和剛才一樣,建立二者的共同接口:
public interface Sender {
public void Send();
}
//其次,建立實作類,郵件發送類實作發送接口:
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
//建立實作類,短信發送類實作發送接口:
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
這貌似和剛剛都一樣嘛<( ̄ˇ ̄)/!注意下面來點不一樣的
//定義發送郵件的工廠類
public class SendMailFactory implements Provider {
@Override
public Sender produce(){
return new MailSender();
}
}
//定義發送短信的工廠類
public class SendSmsFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
//最後提供個工廠類要實作的接口
public interface Provider {
public Sender produce();
}
//測試類
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.Send();
}
}
總結下抽象工廠模式,就是建立多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼,如果你現在想增加一個功能:發微信消息,則隻需做一個實作類,實作Sender接口,同時做一個工廠類,實作Provider接口,就OK了,無需去改動現成的代碼。這樣做,拓展性較好!
參考連結:https://zh.wikipedia.org/wiki/工廠方法
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html