在Java語言中,我們通常有以下幾種創(chuàng)建對象的方式:
(1) 使用new關(guān)鍵字直接創(chuàng)建對象;
(2) 通過反射機(jī)制創(chuàng)建對象;
(3) 通過clone()方法創(chuàng)建對象;
(4) 通過工廠類創(chuàng)建對象(其實(shí)本質(zhì)也是通過new關(guān)鍵字或者反射的方式創(chuàng)建實(shí)例對象)
為什么要用工廠模式
(1) 解耦 :把對象的創(chuàng)建和使用的過程分開。就是Class A 想調(diào)用 Class B ,那么A只是調(diào)用B的方法,而至于B的實(shí)例化,就交給工廠類。
(2)降低代碼重復(fù): 如果創(chuàng)建某個(gè)對象的過程都很復(fù)雜,需要一定的代碼量,而且很多地方都要用到,那么就會(huì)有很多的重復(fù)代碼。
(3) 降低維護(hù)成本 :由于創(chuàng)建過程都由工廠統(tǒng)一管理,所以發(fā)生業(yè)務(wù)邏輯變化,不需要找到所有需要?jiǎng)?chuàng)建對象B的地方去逐個(gè)修正,只需要在工廠里修改即可,降低維護(hù)成本。
工廠模式可以分為三類
(1) 簡單工廠模式(Simple Factory)
(2)工廠方法模式(Factory Method)
(3)抽象工廠模式(Abstract Factory)
?這三種模式從上到下逐步抽象,并且更具一般性。?GOF在《設(shè)計(jì)模式》一書中將工廠模式分為兩類:工廠方法模式(Factory
Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。
簡單工廠模式
簡單工廠模中的角色
工廠(Factory)角色 :簡單工廠模式的核心,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯。工廠類可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對象。
抽象產(chǎn)品(Product)角色:簡單工廠模式所創(chuàng)建的所有對象的父類,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。
具體產(chǎn)品(Concrete Product)角色:簡單工廠模式的創(chuàng)建目標(biāo),所有創(chuàng)建的對象都是充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。
簡單工廠示例
設(shè)計(jì)一個(gè)手機(jī)工廠,這個(gè)手機(jī)工廠可以同時(shí)生產(chǎn)華為手機(jī)、小米手機(jī)
抽象產(chǎn)品角色-手機(jī)接口
public interface Mobile {
public void createMobile();
}
具體產(chǎn)品角色-華為手機(jī)類
public class Huawei implements Mobile {
@Override
public void createMobile() {
System.out.println("生產(chǎn)華為手機(jī)");
}
}
具體產(chǎn)品角色-小米手機(jī)類
public class Xiaomi implements Mobile {
@Override
public void createMobile() {
System.out.println("生產(chǎn)小米手機(jī)");
}
}
工廠角色
public class MobileFactory {
public Mobile cretaeMobie(String type){
switch(type){
case "huawei":
return new Huawei();
case "xiaomi":
return new Xiaomi();
default:
break;
}
return null;
}
}
測試類
public class Customer {
public static void main(String[]
args) {
MobileFactory mobileFactory = new
MobileFactory();
Mobile huaweiMobile =
mobileFactory.cretaeMobie("huawei");
huaweiMobile.createMobile();
Mobile xiaomiMobile =
mobileFactory.cretaeMobie("xiaomi");
xiaomiMobile.createMobile();
}
}
簡單工廠模式只有一個(gè)統(tǒng)一的工廠類,當(dāng)新增一個(gè)類時(shí),要在工廠類中增加相應(yīng)的創(chuàng)建業(yè)務(wù)邏輯,這顯然是違背開閉原則的,我們可以使用工廠方法模式進(jìn)行優(yōu)化
工廠方法模式
工廠方法模式中的角色
抽象工廠(Abstract Factory)角色:是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象的工廠類必須實(shí)現(xiàn)這個(gè)接口。
具體工廠(Concrete Factory)角色 :這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建某一種產(chǎn)品對象。
抽象產(chǎn)品(AbstractProduct)角色 :工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或共同擁有的接口。
具體產(chǎn)品(Concrete Product)角色 :這個(gè)角色實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)
工廠方法模式示例
設(shè)計(jì)一個(gè)華為手機(jī)工廠,一個(gè)小米手機(jī)工廠,分別用來生產(chǎn)華為手機(jī)和小米手機(jī)
抽象產(chǎn)品角色
public interface Mobile {
public void createMobile();
}
具體產(chǎn)品角色-華為手機(jī)類
public class Huawei implements Mobile {
@Override
public void createMobile() {
System.out.println("生產(chǎn)華為手機(jī)");
}
}
具體產(chǎn)品角色-小米手機(jī)類
public class Xiaomi implements Mobile {
@Override
public void createMobile() {
System.out.println("生產(chǎn)小米手機(jī)");
}
}
抽象工廠角色
public interface AbstractFactory {
public Mobile createMobile();
}
具體工廠角色-華為手機(jī)工廠
public class HuaweiFactory implements AbstractFactory{
@Override
public Mobile createMobile() {
return new Huawei();
}
}
具體工廠角色-小米手機(jī)工廠
public class XiaomiFactory implements AbstractFactory{
@Override
public Mobile createMobile() {
return new Xiaomi();
}
}
測試方法
public class Customer {
public static void main(String[] args) {
HuaweiFactory huaweiFactory = new HuaweiFactory();
Mobile huawei = huaweiFactory.createMobile();
huawei.createMobile();
XiaomiFactory xiaomiFactory = new XiaomiFactory();
Mobile xiaomi = xiaomiFactory.createMobile();
xiaomi.createMobile();
}
}
在工廠方法模式中,我們使用某個(gè)工廠生產(chǎn)同一類產(chǎn)品,當(dāng)產(chǎn)品種類非常多時(shí),會(huì)出現(xiàn)大量的與之對應(yīng)的工廠對象,這不是我們所希望的。抽象工廠模式是工廠方法的僅一步深化,在這個(gè)模式中的工廠類不單單可以創(chuàng)建一種產(chǎn)品,而是可以創(chuàng)建一組產(chǎn)品
抽象工廠模式
抽象工廠模式中的角色
抽象工廠(AbstractFactory)角色 :是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象的工廠類必須實(shí)現(xiàn)這個(gè)接口。
具體工廠類(ConreteFactory)角色 :這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建某一種產(chǎn)品對象。
抽象產(chǎn)品(Abstract Product)角色 :工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或共同擁有的接口。
具體產(chǎn)品(Concrete Product)角色 :抽象工廠模式所創(chuàng)建的任何產(chǎn)品對象都是某一個(gè)具體產(chǎn)品類的實(shí)例。在抽象工廠中創(chuàng)建的產(chǎn)品屬于同一產(chǎn)品族。
抽象工廠模式是工廠方法的僅一步深化,在這個(gè)模式中的工廠類不單單可以創(chuàng)建一個(gè)對象,而是可以創(chuàng)建一組對象。這是和工廠方法最大的不同點(diǎn)。
抽象工廠模式實(shí)例
設(shè)計(jì)工廠用來生產(chǎn)華為手機(jī)和小米手機(jī),華為手機(jī)跟小米手機(jī)由不同的cpu和不同屏幕組成
抽象產(chǎn)品角色-cpu接口
public interface Cpu {
public void createCpu();
}
具體產(chǎn)品角色-麒麟cpu
public class KirinCpu implements Cpu {
@Override
public void createCpu() {
System.out.println("生產(chǎn)麒麟cpu");
}
}
具體產(chǎn)品角色-驍龍cpu
public class SnapdragonCpu implements Cpu {
@Override
public void createCpu() {
System.out.println("生產(chǎn)驍龍cpu");
}
}
抽象產(chǎn)品角色-屏幕接口
public interface Screen {
public void createScreen();
}
具體產(chǎn)品角色-三星屏幕
public class SamsungScreen implements Screen {
@Override
public void createScreen() {
System.out.println("生產(chǎn)三星屏幕");
}
}
具體產(chǎn)品角色-LG屏幕
public class LGScreen implements Screen{
@Override
public void createScreen() {
System.out.println("生產(chǎn)LG屏幕");
}
}
抽象工廠角色
public interface AbstractFactory {
public Cpu createCpu();
public Screen createScreen();
}
具體工廠角色-華為手機(jī)工廠
public class HuaweiFactory implements AbstractFactory{
@Override
public Cpu createCpu() {
return new KirinCpu();
}
@Override
public Screen createScreen() {
return new LGScreen();
}
}
具體工廠角色-小米手機(jī)工廠
public class XiaomiFactory implements AbstractFactory{
@Override
public Cpu createCpu() {
return new SnapdragonCpu();
}
@Override
public Screen createScreen() {
return new SamsungScreen();
}
}
測試類
public class Customer {
public static void main(String[] args) {
HuaweiFactory huaweiFactory = new HuaweiFactory();
Cpu huaweiCpu = huaweiFactory.createCpu();
huaweiCpu.createCpu();
Screen huaweiScreen = huaweiFactory.createScreen();
huaweiScreen.createScreen();
XiaomiFactory xiaomiFactory = new XiaomiFactory();
Cpu xiaomiCpu = xiaomiFactory.createCpu();
xiaomiCpu.createCpu();
Screen xiaomiScreen = xiaomiFactory.createScreen();
xiaomiScreen.createScreen();
}
}
抽象工廠的工廠和工廠方法的區(qū)別:
廠方法模式中的工廠只生產(chǎn)單一的產(chǎn)品,而抽象工廠模式中的工廠生產(chǎn)多個(gè)產(chǎn)品,工廠方法模式的具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例,而抽象工廠模式可以創(chuàng)建多個(gè)。
工廠模式適用的一些場景
(1)對象的創(chuàng)建過程/實(shí)例化準(zhǔn)備工作很復(fù)雜,需要初始化很多參數(shù)、查詢數(shù)據(jù)庫等。
(2)類本身有好多子類,這些類的創(chuàng)建過程在業(yè)務(wù)中容易發(fā)生改變,或者對類的調(diào)用容易發(fā)生改變。
(3)客戶端不需要知道它所創(chuàng)建的對象的類,只知道創(chuàng)建它的工廠名就完成了創(chuàng)建過程。