工廠(chǎng)模式
實(shí)現(xiàn)了創(chuàng)建者和調(diào)用者的分離。
詳細(xì)分類(lèi)
- 簡(jiǎn)單工廠(chǎng)模式
- 工廠(chǎng)方法模式
- 抽象工廠(chǎng)模式
核心本質(zhì)
- 實(shí)例化對(duì)象,用工廠(chǎng)方法代替new操作;
- 將選擇實(shí)現(xiàn)類(lèi)、創(chuàng)建對(duì)象統(tǒng)一管理化控制,從而將調(diào)用者和我們的實(shí)現(xiàn)類(lèi)解耦。
簡(jiǎn)單工廠(chǎng)
要點(diǎn)
- 簡(jiǎn)單工廠(chǎng)也稱(chēng)靜態(tài)工廠(chǎng)模式,就是工廠(chǎng)類(lèi)一般是使用靜態(tài)方法,通過(guò)接收的參數(shù)不同,來(lái)返回不同的對(duì)象實(shí)例。
- 不符合開(kāi)閉原則,當(dāng)要增加新產(chǎn)品時(shí),不得不修改內(nèi)部代碼。
類(lèi)圖:

image
代碼實(shí)現(xiàn):
用簡(jiǎn)單工廠(chǎng)模式模擬一個(gè)自動(dòng)生產(chǎn)奧迪和比亞迪的車(chē)廠(chǎng),創(chuàng)建奧迪和比亞迪實(shí)例。
/*
* 車(chē)輛類(lèi)的接口
*/
public interface Car {
void run();
}
/*
* 奧迪車(chē)
*/
public class Aodi implements Car{
@Override
public void run() {
System.out.println("開(kāi)奧迪!");
}
}
/*
* 比亞迪車(chē)
*/
public class Byd implements Car{
@Override
public void run() {
System.out.println("開(kāi)比亞迪!");
}
}
/*
* 簡(jiǎn)單工廠(chǎng)
*/
public class CarFactory {
public static Car createCar(String type) {
if(type.equals("Aodi"))
return new Aodi();
else if(type.equals("Byd"))
return new Byd();
else
return null;
}
}
/*
* 客戶(hù)端
*/
public class Client {
public static void main(String[] args) {
//生產(chǎn)一輛奧迪
Car aodi = CarFactory.createCar("Aodi");
//生產(chǎn)一輛比亞迪
Car byd = CarFactory.createCar("Byd");
aodi.run();
byd.run();
}
}
工廠(chǎng)方法
要點(diǎn)
- 為了避免簡(jiǎn)單工廠(chǎng)的缺點(diǎn)(無(wú)法增加新產(chǎn)品),不完全滿(mǎn)足OCP(開(kāi)閉原則)。
- 工廠(chǎng)方法模式和簡(jiǎn)單工廠(chǎng)模式的最大不同在于,簡(jiǎn)單工廠(chǎng)模式只有一個(gè)(對(duì)于一個(gè)項(xiàng)目或者一個(gè)獨(dú)立模塊而言)工廠(chǎng)類(lèi),而工廠(chǎng)方法模式有一組實(shí)現(xiàn)了相同接口的工廠(chǎng)類(lèi)。
類(lèi)圖

image
代碼實(shí)現(xiàn)
創(chuàng)建一個(gè)工廠(chǎng)接口,用來(lái)擴(kuò)展工廠(chǎng)類(lèi)。下面將工廠(chǎng)分為了奧迪工廠(chǎng)和比亞迪工廠(chǎng)兩個(gè)分工廠(chǎng),分別用來(lái)生產(chǎn)奧迪車(chē)和比亞迪車(chē)。
/*
* 車(chē)輛類(lèi)的接口
*/
public interface Car {
void run();
}
/*
* 奧迪車(chē)
*/
public class Aodi implements Car{
@Override
public void run() {
System.out.println("開(kāi)奧迪!");
}
}
/*
* 比亞迪車(chē)
*/
public class Byd implements Car{
@Override
public void run() {
System.out.println("開(kāi)比亞迪!");
}
}
/*
* 工廠(chǎng)類(lèi)接口
*/
public interface Factory {
Car createCar();
}
/*
* 生產(chǎn)奧迪車(chē)的分工廠(chǎng)
*/
public class AudiFactory implements Factory{
@Override
public Car createCar() {
return new Audi();
}
}
/*
* 生產(chǎn)比亞迪的分工廠(chǎng)
*/
public class BydFactory implements Factory{
@Override
public Car createCar() {
return new Byd();
}
}
/*
* 客戶(hù)端
*/
public class Client {
public static void main(String[] args) {
//創(chuàng)建奧迪車(chē)
Car audi = new AudiFactory().createCar();
audi.run();
}
}
抽象工廠(chǎng)
要點(diǎn)
- 用來(lái)生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品(對(duì)于新增的產(chǎn)品無(wú)能為力,但支持增加產(chǎn)品族——不同產(chǎn)品的組合)
- 抽象工廠(chǎng)模式是工廠(chǎng)模式的升級(jí)版本,在有多個(gè)業(yè)務(wù)品種、業(yè)務(wù)分類(lèi)時(shí),通過(guò)抽象工廠(chǎng)模式產(chǎn)生需要的對(duì)象是一種非常好的解決方式。
類(lèi)圖:

image
代碼實(shí)現(xiàn):
/*
* 發(fā)動(dòng)機(jī)產(chǎn)品類(lèi)的接口
*/
public interface Engine {
void run();
void start();
}
/*
* 高配的發(fā)動(dòng)機(jī)
*/
public class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("轉(zhuǎn)的快!");
}
@Override
public void start() {
System.out.println("啟動(dòng)快!");
}
}
/*
* 低配的發(fā)動(dòng)機(jī)
*/
public class LowEngine implements Engine{
@Override
public void run() {
System.out.println("轉(zhuǎn)的慢!");
}
@Override
public void start() {
System.out.println("啟動(dòng)慢!");
}
}
/*
* 座椅類(lèi)產(chǎn)品的接口
*/
public interface Seat {
void massage();
}
/*
* 高配真皮座椅
*/
public class LuxurySeat implements Seat{
@Override
public void massage() {
System.out.print("可以自動(dòng)按摩");
}
}
/*
* 低配普通座椅
*/
public class LowSeat implements Seat{
@Override
public void massage() {
System.out.print("不可以自動(dòng)按摩");
}
}
/*
* 工廠(chǎng)類(lèi)接口
*/
public interface CarFactory {
Engine createEngine();
Seat createSeat();
}
/*
* 高配車(chē)工廠(chǎng)
*/
public class LuxuryCarFactory implements CarFactory{
public Engine createEngine() {
return new LuxuryEngine();
}
public Seat createSeat() {
return new LuxurySeat();
}
}
/*
* 低配車(chē)工廠(chǎng)
*/
public class LowCarFactory implements CarFactory{
public Engine createEngine() {
return new LowEngine();
}
public Seat createSeat() {
return new LowSeat();
}
}
/*
* 客戶(hù)端
*/
public class Client {
public static void main(String[] args) {
//高配汽車(chē)
CarFactory factory1 = new LuxuryCarFactory();
Engine e = factory1.createEngine();
e.run();
e.start();
System.out.println("---------------------");
//低配汽車(chē)
CarFactory factory2 = new LowCarFactory();
Engine e2 = factory2.createEngine();
e2.run();
e2.start();
}
}
總結(jié)
工廠(chǎng)模式要點(diǎn)
- 簡(jiǎn)單工廠(chǎng)模式(靜態(tài)工廠(chǎng)模式)
雖然某種程度不符合設(shè)計(jì)原則,但實(shí)際卻使用最多。
- 工廠(chǎng)方法模式
不修改已有類(lèi)的前提下,通過(guò)增加新的工廠(chǎng)類(lèi)實(shí)現(xiàn)擴(kuò)展。
- 抽象工廠(chǎng)模式
不可以增加產(chǎn)品,可以增加產(chǎn)品族。
應(yīng)用場(chǎng)景:
- JDK的Calendar的getInstance方法
- JDBC中的Connection對(duì)象的獲取
- Hibernate中SessionFactory創(chuàng)建Session
- Spring中的IOC容器創(chuàng)建管理bean對(duì)象
- XML解析時(shí)的DocumentBuilderFactory創(chuàng)建解析器對(duì)象
- 反射中Class對(duì)象的newInstance()