設(shè)計模式系列文章
目錄
設(shè)計模式系列文章
前言
一、簡單工廠模式
二、工廠方法模式
三、抽象工廠模式
總結(jié)
前言
最近在學(xué)習(xí)一些Java設(shè)計模式的概念,設(shè)計模式誕生的目的,我認(rèn)為是可以使得寫出的代碼具有更好的邏輯性,減少了大量冗余代碼來進(jìn)行重復(fù)而繁瑣的操作,也更好的提升了復(fù)用性。所以學(xué)習(xí)并且能夠使用合理的設(shè)計模式可以讓我們的代碼更加美觀,優(yōu)雅,結(jié)構(gòu)更加清晰。
本次內(nèi)容對Java中的工廠模式進(jìn)行講解,工廠模式又可以分為三種
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ” 簡單工廠,工廠方法, 抽象工廠 ”
一、簡單工廠模式
工廠模式,主要用于創(chuàng)建對象時的一系列操作。
在我們平時創(chuàng)建對象的時候,一般使用New關(guān)鍵字來進(jìn)行創(chuàng)建。
ClassA?a?=?new?ClassA();
ClassB?b?=?new?ClassB();
?我們使用New關(guān)鍵字創(chuàng)建對象,會根據(jù)括號內(nèi)的參數(shù)在構(gòu)造函數(shù)里對實例化對象進(jìn)行初始化。
然而,我們創(chuàng)建一個對象的時候,可能需要對他進(jìn)行一些初始化操作,例如查詢數(shù)據(jù)庫,對屬性賦值等等。如果我們把這些操作也全部寫到構(gòu)造函數(shù)中。那構(gòu)造函數(shù)就變得很長很長,可讀性大大降低。
針對這種情況,我們可以引入 ” 工廠 “ 的概念,我們不通過New關(guān)鍵字去創(chuàng)建對象了,我們直接去創(chuàng)建一個工廠,讓工廠去幫我們創(chuàng)建對象。
例如,我們創(chuàng)建了一個專門生產(chǎn)手機(jī)的工廠,這個工廠可以生產(chǎn)梨子手機(jī),菠蘿手機(jī)。
那么首先我們要創(chuàng)建梨子手機(jī)和菠蘿手機(jī)這兩個類,這里我實現(xiàn)了一個Phone接口,表明梨子手機(jī)和菠蘿手機(jī)都是一個 ” Phone “類型的類,然后我們在創(chuàng)建的時候返回Phone類型的就可以了。
public interface Phone {
void show();
}
public class LiPhone implements Phone {
@Override
public void show() {
System.out.println("我是梨子手機(jī)");
}
}
public class BoPhone implements Phone {
@Override
public void show(){
System.out.println("我是菠蘿手機(jī)");
}
}
?然后我們再創(chuàng)建一個手機(jī)工廠,來生產(chǎn)手機(jī)。
這里應(yīng)該很通俗易懂,我們再創(chuàng)建手機(jī)的時候,只需要給定規(guī)定好的number,工廠就知道該生產(chǎn)什么手機(jī)了,然后也可以按照我們的意愿去進(jìn)行初始化。
public class PhoneFactory{
public Phone createPhone(Integer number) {
Phone phone = null;
if(number == 1){
phone = new LiPhone();
// .....
// 梨子手機(jī)的初始化代碼
}else if(number == 2){
phone = new BoPhone();
// .....
// 菠蘿的初始化代碼
}
return phone;
}
}
然而這么做其實又會衍生出一個問題,那就是當(dāng)我們有很多牌子手機(jī)的時候,比如我們還有錘子手機(jī),番茄手機(jī),土豆手機(jī)。那我們每多一個手機(jī),就要去修改一次手機(jī)工廠的 if else?判斷,這違背了設(shè)計模式的一個原則 “ 對修改關(guān)閉,對拓展開啟 ”
(注:所謂面向?qū)ο蟮拈_放-封閉原則,就是在程序中對“擴(kuò)展”開放,對“修改”封閉。如果每次業(yè)務(wù)改動都要增加新的if-else,就涉及對舊有代碼的修改,不但容易出錯,可讀性也不好。)
那么怎么解決呢,我們可以使用下面提到的工廠方法模式。
二、工廠方法模式
前面我們提到,為了解決簡單工廠模式中通過工廠創(chuàng)建對象 if esle 語句過多的問題可以使用工廠方法模式。而工廠方法模式的主要原理就是,我們把每一個要創(chuàng)建的產(chǎn)品對象獨立分配一個工廠,提取一個工廠接口出來,獨立分配的工廠作為工廠接口的實現(xiàn)類,這樣我們在創(chuàng)建工廠——再通過工廠創(chuàng)建對象的過程中,工廠就是唯一確定了的,所以創(chuàng)建的對象也是唯一確定的,不需要再使用過多的判斷語句了。
所以我們對之前的工廠類進(jìn)行修改先.
現(xiàn)在我們提取出了一個工廠接口,接口中有生產(chǎn)手機(jī)的方法,然后我們?yōu)槔孀邮謾C(jī)和菠蘿手機(jī)都創(chuàng)建一個工廠類去實現(xiàn)接口,在實現(xiàn)類的 createPhone 方法中創(chuàng)建手機(jī),這樣如果我們以后有了其他手機(jī),只需要再增加手機(jī)的工廠類去實現(xiàn)接口就可以了。
public interface PhoneFactory {
Phone createPhone();
}
public class LiFactory implements PhoneFactory{
@Override
public Phone createPhone() {
Phone phone = new LiPhone();
// .....
// 初始化代碼
return phone;
}
}
public class BoFactory implements PhoneFactory{
@Override
public Phone createPhone() {
Phone phone = new BoPhone();
// .....
// 初始化代碼
return phone;
}
}
測試方法
public class Test {
public static void main(String[] args) {
PhoneFactory factoryA = new LiFactory();
PhoneFactory factoryB = new BoFactory();
Phone phoneA = factoryA.createPhone();
Phone phoneB = factoryB.createPhone();
phoneA.show();
phoneB.show();
}
}
?輸出:
我是梨子手機(jī)
我是菠蘿手機(jī)
那么,?其實我們可以顯而易見的發(fā)現(xiàn),工廠方法模式雖然可以確保我們每一個手機(jī)對應(yīng)一個工廠,而且需要創(chuàng)建手機(jī)的時候只需要通過對應(yīng)工廠創(chuàng)建就可以了,但是這樣隨著我們的產(chǎn)品越來越多,工廠的實現(xiàn)類也越來越多,看的人頭都暈了。
那么,我們可以使用 “ 抽象工廠 ”模式來解決這個問題。比如我們的梨子手機(jī)和菠蘿手機(jī)分別來自梨子廠和菠蘿廠。那梨子廠和菠蘿廠它們也有遠(yuǎn)大的理想??!他們不想只做手機(jī)! 他們要搞吧來福,搞把AK,做大做強(qiáng)!
梨子廠要做手機(jī)和電腦,菠蘿見狀,心想那我指定也得卷起來啊,于是菠蘿老板下令,我們也要做手機(jī)和電腦!
三、抽象工廠模式
從上面的情景我們可以分析得到,梨子廠和菠蘿廠都不甘現(xiàn)狀,他們不禁想做手機(jī),還想做電腦。
那我們需要去創(chuàng)建一個手機(jī)廠的同時再去創(chuàng)建一個電腦廠嗎??
那當(dāng)然不需要了,我們可以創(chuàng)建一個工廠接口,這個工廠既可以做手機(jī),又可以做電腦
我們再創(chuàng)建實現(xiàn)類工廠,梨子廠和菠蘿廠。因為梨子廠和菠蘿廠都實現(xiàn)了工廠接口,所以他們都有創(chuàng)建手機(jī)和電腦的流水線(方法)
那就簡單了,我們在各自的流水線中創(chuàng)建自己的產(chǎn)品不就行了嘛
直接上代碼??!
哦不 先上個圖 畫的丑陋,帥哥美女們將就看看
上代碼?。。?/span>
首先安排兩個產(chǎn)品的接口,手機(jī)接口和電腦接口,以及他們的實現(xiàn)類。
public interface Phone {
void showPhone();
}
public class LiPhone implements Phone {
@Override
public void showPhone(){
System.out.println("我是梨子手機(jī)");
}
}
public class BoPhone implements Phone {
@Override
public void showPhone(){
System.out.println("我是菠蘿手機(jī)");
}
}
public interface Computer {
void showComputer();
}
public class LiComputer implements Computer {
@Override
public void showComputer() {
System.out.println("我是梨子電腦");
}
}
public class BoComputer implements Computer {
@Override
public void showComputer() {
System.out.println("我是菠蘿電腦");
}
}
然后再安排一下我們的重頭戲,抽象工廠。
public interface IFactory {
//創(chuàng)建口罩
Phone createPhone();
//創(chuàng)建防護(hù)服
Computer createComputer();
}
public class LiFactory implements IFactory {
@Override
public Phone createPhone() {
Phone phone = new LiPhone();
// .....
// 初始化代碼
return phone;
}
@Override
public Computer createComputer() {
Computer computer = new LiComputer();
// .....
// 初始化代碼
return computer;
}
}
public class BoFactory implements IFactory {
@Override
public Phone createPhone() {
Phone phone = new BoPhone();
// .....
// 初始化代碼
return phone;
}
@Override
public Computer createComputer() {
Computer computer = new BoComputer();
// .....
// 初始化代碼
return computer;
}
}
?最后測試一下來看看
public class Test {
public static void main(String[] args) {
IFactory factoryA = new LiFactory();
IFactory factoryB = new BoFactory();
//創(chuàng)建低端口罩
Phone phoneA = factoryA.createPhone();
//創(chuàng)建高端口罩
Phone phoneB = factoryB.createPhone();
//創(chuàng)建低端防護(hù)服
Computer computerA = factoryA.createComputer();
//創(chuàng)建高端防護(hù)服
Computer computerB = factoryB.createSuit();
phoneA.showPhone();
phoneB.showPhone();
computerA.showComputer();
computerB.showComputer();
}
}
?輸出:
我是梨子手機(jī)
我是菠蘿手機(jī)
我是梨子電腦
我是菠蘿電腦
大功告成~ ???文章來源:http://www.zghlxwxcb.cn/news/detail-411848.html
總結(jié)
現(xiàn)在越來越多Java開發(fā)方面的工作在招聘的要求上都會要求應(yīng)聘者要熟知常見的設(shè)計模式,以及在面試的過程中也經(jīng)常會問道設(shè)計模式相關(guān)的知識,所以設(shè)計模式的學(xué)習(xí)是非常重要的,而且學(xué)習(xí)了還要會融會貫通,在寫代碼的時候,遇到有重復(fù)的代碼就可以思考一下是否可以將重復(fù)的代碼抽取出來進(jìn)行封裝或者其他操作。文章來源地址http://www.zghlxwxcb.cn/news/detail-411848.html
到了這里,關(guān)于Java設(shè)計模式——工廠模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!