什么是工廠設(shè)計(jì)模式?
工廠設(shè)計(jì)模式,顧名思義,就是用來(lái)生產(chǎn)對(duì)象的,在java中,萬(wàn)物皆對(duì)象,這些對(duì)象都需要?jiǎng)?chuàng)建,如果創(chuàng)建的時(shí)候直接new該對(duì)象,就會(huì)對(duì)該對(duì)象耦合嚴(yán)重,假如我們要更換對(duì)象,所有new對(duì)象的地方都需要修改一遍,這顯然違背了軟件設(shè)計(jì)的開(kāi)閉原則,如果我們使用工廠來(lái)生產(chǎn)對(duì)象,我們就只和工廠打交道就可以了,徹底和對(duì)象解耦,如果要更換對(duì)象,直接在工廠里更換該對(duì)象即可,達(dá)到了與對(duì)象解耦的目的;所以說(shuō),工廠模式最大的優(yōu)點(diǎn)就是:解耦
簡(jiǎn)單工廠模式(靜態(tài)工廠模式)
- 簡(jiǎn)單工廠模式是屬于創(chuàng)建型模式,是工廠模式的一種。簡(jiǎn)單工廠模式是由一個(gè)工廠對(duì)象決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例。簡(jiǎn)單工廠模式是工廠模式家族中最簡(jiǎn)單實(shí)用的模式
- 簡(jiǎn)單工廠模式:定義了一個(gè)創(chuàng)建對(duì)象的類,由這個(gè)類來(lái)封裝實(shí)例化對(duì)象的行為(代碼)
- 在軟件開(kāi)發(fā)中,當(dāng)我們會(huì)用到大量的創(chuàng)建某種、某類或者某批對(duì)象時(shí),就會(huì)使用到工廠模式.
◆雖然某種程度上不符合設(shè)計(jì)原則,但實(shí)際使用最多!
我有一個(gè)汽車工廠,可以生產(chǎn)各種汽車對(duì)象
public class CarFactory {
public static Car GetCar(String car){
if(car.equals("寶馬")){
return new BaoMa();
}else if(car.equals("奔馳")){
return new BenChi();
}else{
return null;
}
}
}
汽車生產(chǎn)接口
public interface Car {
void name();
}
具體類 寶馬 實(shí)現(xiàn)接口
public class BaoMa implements Car {
@Override
public void name() {
System.out.println("寶馬");
}
}
具體類 奔馳 實(shí)現(xiàn)接口
public class BenChi implements Car {
@Override
public void name() {
System.out.println("奔馳");
}
}
使用
Car car=CarFactory.GetCar("寶馬");
Car car1=CarFactory.GetCar("奔馳");
car1.name();
car.name();
但是這時(shí),我想要獲得獲得其他汽車對(duì)象,我就得修改汽車工廠,這就違背了設(shè)計(jì)模式的開(kāi)閉原則。
開(kāi)放-關(guān)閉原則表示軟件實(shí)體 (類、模塊、函數(shù)等等) 應(yīng)該是可以被擴(kuò)展的,但是不可被修改
工廠方法模式
- 介紹:
定義了一個(gè)創(chuàng)建對(duì)象的抽象方法,由子類決定要實(shí)例化的類。工廠方法模式將對(duì)象的實(shí)例化推遲到子類。 - 適用場(chǎng)景:
消費(fèi)者不關(guān)心它所要?jiǎng)?chuàng)建對(duì)象的類(產(chǎn)品類)的時(shí)候。
消費(fèi)者知道它所要?jiǎng)?chuàng)建對(duì)象的類(產(chǎn)品類),但不關(guān)心如何創(chuàng)建的時(shí)候。
◆不修改已有類的前提下,通過(guò)增加新的工廠類實(shí)現(xiàn)擴(kuò)展,
工廠接口:
public interface CarFactory {
Car getCar();
}
寶馬工廠
public class BaoMaFactory implements CarFactory {
@Override
public Car getCar() {
return new BaoMa();
}
}
奔馳工廠
public class BenChiFactory implements CarFactory {
@Override
public Car getCar() {
return new BenChi();
}
}
使用:
Car car=new BaoMaFactory().getCar();
Car car1=new BenChiFactory().getCar();
car1.name(); //奔馳
car.name(); //寶馬
抽象工廠模式
- 介紹:
- 抽象工廠模式:定義了一個(gè) interface 用于創(chuàng)建相關(guān)或有依賴關(guān)系的對(duì)象簇,而無(wú)需指明具體的類
- 抽象工廠模式可以將簡(jiǎn)單工廠模式和工廠方法模式進(jìn)行整合。
- 從設(shè)計(jì)層面看,抽象工廠模式就是對(duì)簡(jiǎn)單工廠模式的改進(jìn)(或者稱為進(jìn)一步的抽象)。
- 將工廠抽象成兩層,AbsFactory(抽象工廠) 和 具體實(shí)現(xiàn)的工廠子類。程序員可以根據(jù)創(chuàng)建對(duì)象類型使用對(duì)應(yīng)的工廠子類。這樣將單個(gè)的簡(jiǎn)單工廠類變成了工廠簇,更利于代碼的維護(hù)和擴(kuò)展。
- 適用場(chǎng)景
1、客戶端(應(yīng)用層)不依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、實(shí)現(xiàn)等細(xì)節(jié)
2、強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對(duì)象(屬于同一產(chǎn)品族)一起使用創(chuàng)建對(duì)象需要大量重復(fù)的代碼
3、提供一個(gè)產(chǎn)品類的庫(kù),所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶端不依賴于具體實(shí)現(xiàn)
◆不可以增加產(chǎn)品,可以增加產(chǎn)品族!
//工廠接口
public interface IProductFactory {
//生產(chǎn)手機(jī)
IphoneProduct iphoneproduct();
//生產(chǎn)路由器
IrouterProject irouterproject();
}
//華為工廠
public class HuaweiFactory implements IProductFactory {
@Override
public IphoneProduct iphoneproduct() {
return new HuaweiPhone();
}
@Override
public IrouterProject irouterproject() {
return new HuaweiRouter();
}
}
//小米工廠
public class XiaomiFactory implements IProductFactory {
@Override
public IphoneProduct iphoneproduct() {
return new XiaomiPhone();
}
@Override
public IrouterProject irouterproject() {
return new XiaomiRouter();
}
}
//手機(jī)接口
public interface IphoneProduct {
void start();
void shutdown();
void callup();
void sendSMS();
}
//華為手機(jī)
public class HuaweiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("開(kāi)啟華為手機(jī)");
}
@Override
public void shutdown() {
System.out.println("關(guān)閉華為手機(jī)");
}
@Override
public void callup() {
System.out.println("華為打電話");
}
@Override
public void sendSMS() {
System.out.println("華為發(fā)信息");
}
}
//小米手機(jī)
public class XiaomiPhone implements IphoneProduct {
@Override
public void start() {
System.out.println("開(kāi)啟小米手機(jī)");
}
@Override
public void shutdown() {
System.out.println("關(guān)閉小米手機(jī)");
}
@Override
public void callup() {
System.out.println("小米打電話");
}
@Override
public void sendSMS() {
System.out.println("小米發(fā)信息");
}
}
//路由器接口
public interface IrouterProject {
void start();
void shutdown();
void openWife();
void setting();
}
//華為路由
public class HuaweiRouter implements IrouterProject {
@Override
public void start() {
System.out.println("開(kāi)啟華為路由器");
}
@Override
public void shutdown() {
System.out.println("關(guān)閉華為路由器");
}
@Override
public void openWife() {
System.out.println("打開(kāi)華為wifi");
}
@Override
public void setting() {
System.out.println("華為設(shè)置");
}
}
//小米路由
public class XiaomiRouter implements IrouterProject {
@Override
public void start() {
System.out.println("開(kāi)啟小米路由器");
}
@Override
public void shutdown() {
System.out.println("關(guān)閉小米路由器");
}
@Override
public void openWife() {
System.out.println("打開(kāi)小米 wifi");
}
@Override
public void setting() {
System.out.println("小米設(shè)置");
}
}
抽象工廠可以解決一系列的產(chǎn)品生產(chǎn)的需求,對(duì)于大批量,多系列的產(chǎn)品,用抽象工廠可以更好的管理和擴(kuò)展;
三種工廠方式總結(jié):
1、對(duì)于簡(jiǎn)單工廠和工廠方法來(lái)說(shuō),兩者的使用方式實(shí)際上是一樣的,如果對(duì)于產(chǎn)品的分類和名稱是確定的,數(shù)量是相對(duì)固定的,推薦使用簡(jiǎn)單工廠模式;
2、抽象工廠用來(lái)解決相對(duì)復(fù)雜的問(wèn)題,適用于一系列、大批量的對(duì)象生產(chǎn);
應(yīng)用場(chǎng)景:
◆JDK中Calendar的getlnstance方法(簡(jiǎn)單工廠模式)
◆JDBC中的Connection對(duì)象的獲取
◆Spring中IOC容器創(chuàng)建管理bean對(duì)象.反射中Class對(duì)象的newInstance方法