工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。
在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。
工廠模式分爲三種:簡單工廠模式、工廠方法模式、抽象工廠模式。
一、簡單工廠模式<對象抽離接口>
簡單工廠模式適用於工廠類負責創建的對象比較少的情況,並且 客戶端只需要傳入工廠類的參數,不需要關心創建對象的細節。
1、創建接口對象
// 創建手機接口對象
public interface Phone{
// 定義一個發送信息的接口
public void send();
}
2、創建SmartPhone對象,並實現接口
public class SmartPhone implements Phone{
@Override
public void send() {
//智能機可以發微信
System.out.println("智能手機發微信");
}
}
3、創建OldMachine對象,並實現接口
public class OldMachine implements Phone{
@Override
public void send() {
//老年機只能發短信
System.out.println("老年機發短信");
}
}
4、創建工廠類Factory
public class Factory{
public Phone createPhone(String type){
if("smartPhone".equals(type)){
return new SmartPhone();
}else if("oldMachine".equals(type)){
return new OldMachine();
}
return null;
}
}
5、編寫測試類
public class Test {
public static void main(String[] args){
Factory factory=new Factory();
Phone phone_1=factory.send("oldMachine");
phone_1.send();
Phone phone_2=factory.send("smartPhone");
phone_2.send();
}
}
打印結果爲:
老年機發短信
智能手機發微信
以上雖然實現了由自己創建對象改爲由工廠創建對象,但是存在一個問題,如果需要增加一個兒童手機【爲了孩子們的健康,只能讓他打電話、發短信】,那麼如果我們還想使用工廠模式創建對象,只能是修改Factory工廠類,這樣的話就違反了我們的開閉原則,對於項目的擴展也是不利的,由此引出了工廠方法模式。
二、工廠方法模式<工廠抽離接口>
1、首先我們先創建一個工廠接口
public interface Factory{
public Phone createPhone();
}
2、創建一個智能手機工廠,並實現工廠接口
public class SmartPhoneFactory implements Factory{
@Override
public Phone createPhone(){
return new SmartPhone();
}
}
3、創建一個老年機工廠,並實現工廠接口
public class OldMachineFactory implements Factory{
@Override
public Phone createPhone(){
return new OldMachine();
}
}
4、創建測試類
public class Test {
public static void main(String[] args){
Factory factory=new SmartPhoneFactory();
Phone phone=factory.createPhone();
phone.send();
}
}
5、控制檯打印結果
智能手機發微信
對於工廠方法模式,則規避了開閉原則,如果有新的手機加入的話,我們只需要爲其再創建一個工廠就可以了,感覺是不是比第一個更利於擴展。但此方法仍然有一個比較嚴重的問題,就是當我們的對象非常多的時候,那麼對應的工廠也就十分龐大,無疑是增加代碼的複雜度。
當然還有多個工廠方法,即一個工廠類中含有創建多個對象的方法。此方法也是違背了開閉原則,所以就不在討論。
三、抽象工廠模式<對象及工廠抽離爲接口>
1、定義手機接口
public interface Phone {
public void send();
}
2、智能手機實現類
public class SmartPhone implements Phone {
@Override
public void send() {
System.out.println("智能手機發微信");
}
}
3、老年機實現類
public class OldMachine implements Phone{
@Override
public void send() {
System.out.println("老年機發短信");
}
}
4、工廠接口類
public interface Factory {
public Phone createPhone();
}
5、智能手機工廠實現類
public class SmartPhoneFactory implements Factory {
@Override
public Phone createPhone() {
return new smartPhone();
}
}
6、老年機工廠實現類
public class OldMachineFactory implements Factory {
@Override
public Phone createPhone() {
return new oldMachine();
}
}
7、測試類
public class Test {
public static void main(String[] args){
Factory factory= new SmartPhoneFactory();
Phone phone=factory.createPhone();
phone.send();
}
}
測試結果爲:
智能手機發微信
由此,抽象工廠模式已經結束,如果有新增的產品只需要增加產品實現類及該產品的工廠實現類就可以了。但是如果該產品需要增加一個新功能call 那麼還是需要修改源代碼,也是不符合開閉原則。當然有時我們不需要嚴格按照開閉原則來做,只要產品不頻繁升級,根據實際情況可以不遵守開閉原則,比如說每年升級一次,又有何不可呢?