三種工廠模式總述
工廠模式實現了建立者和呼叫者的分離。 – 詳細分類:
1.簡單工廠模式
2.工廠方法模式
3.抽象工廠模式
工廠模式的核心本質: – 例項化物件,用工廠方法代替new操作。 – 將選擇實現類、建立物件統一管理和控制。從而將呼叫者跟我們的實現類解耦。
工廠模式:
– 簡單工廠模式 :用來生產同一等級結構中的任意產品。(對於增加新的產品,需要修改已 有程式碼)
– 工廠方法模式 :用來生產同一等級結構中的固定產品。(支援增加任意產品)
– 抽象工廠模式 :用來生產不同產品族的全部產品。(對於增加新的產品,無能為力;支援 增加產品族)
不使用工廠方法的情況
程式碼的耦合度高,不易擴充套件
public class Client01 { //呼叫者
public static void main(String[] args) {
Car c1 = new Audi();
Car c2 = new Byd();
c1.run();
c2.run();
}
}
1、簡單工廠模式
簡單工廠模式也叫靜態工廠模式,就是工廠類一般是使用靜態方法,通過接收的引數的不同來返回不同的物件例項。但對於增加新產品無能為力!不修改程式碼的話,是無法擴充套件的。
簡單工廠一:
傳入一個名字,根據名字返回相應的產品
public class CarFactory {
public static Car createCar(String type){
Car c = null;
if("奧迪".equals(type){
c = new Audi();
}else if("賓士".equals(type){
c = new Benz();
}
return c;
}
}
簡單工廠二:
直接創建出來
public class CarFactory {
public static Car createAudi(){
return new Audi();
}
public static Car createBenz(){
return new Benz();
}
}
2、工廠方法模式
為了避免簡單工廠模式的缺點,不完全滿足OCP。
工廠方法模式和簡單工廠模式最大的不同在於,簡單工廠模式只有一個(對於一個專案或者一個獨立模組而言)工廠類,而工廠方法模式有一組實現了相同介面的工廠類。這樣做的目的,是在需要工廠建立新的類時,不用修改已有的程式碼,而是通過新增加工廠類的方式實現。
這樣我們就需要定義一個工廠類的介面,具體的工廠來生產具體的產品。通過一個UML圖來說明:
每一個具體的工廠只負責生產具體的產品,這樣在需要工廠生產新的產品時,不用修改原來的程式碼。
public interface FruitFactory { //定義一個介面工廠
Fruit createFruit();
}
class AppleFactory implements FruitFactory { //具體的建立型別工廠
@Override
public Fruit createFruit() {
return new Apple();
}
}
class OrangeFactory implements FruitFactory{ //具體的建立型別工廠
@Override
public Fruit createFruit() {
return new Orange();
}
}
定義水果:
public class Apple implements Fruit{ //定義水果
@Override
public void plant() {
System.out.println("蘋果種植");
}
@Override
public void cultivate() {
System.out.println("蘋果培養");
}
}
class Orange implements Fruit {
@Override
public void plant() {
System.out.println("橘子種植");
}
@Override
public void cultivate() {
System.out.println("橘子培養");
}
}
使用:
* 工廠方法設計模式
* 包涵:
* 抽象產品(用與建立具體的產品)
* 具體產品(繼承或實現抽象產品)
* 抽象工廠(工廠父類,工廠方法模式的核心)
* 具體工廠,用於生產具體的一種類
* 符合開閉原則(ocp),擴充套件方便
* */
public class client {
public static void main(String[] args) {
Fruit app=new AppleFactory().createFruit();//使用工廠建立物件
app.cultivate();
app.plant();
System.out.println("===============");
Fruit ora=new OrangeFactory().createFruit();
ora.plant();
ora.cultivate();
}
}
3、簡單工廠模式和工廠方法模式PK:
結構複雜度:從這個角度比較,顯然簡單工廠模式要佔優。簡單工廠模式只需一個工廠類,而工廠方法模式的工廠類隨著產品類個數增加而增加,這無疑會使類的個數越來越多,從而增加了結構的複雜程度。
程式碼複雜度:程式碼複雜度和結構複雜度是一對矛盾,既然簡單工廠模式在結構方面相對簡潔,那麼它在程式碼方面肯定是比工廠方法模式複雜的了。簡單工廠模式的工廠類隨著產品類的增加需要增加很多方法(或程式碼),而工廠方法模式每個具體工廠類只完成單一任務,程式碼簡潔。
客戶端程式設計難度:工廠方法模式雖然在工廠類結構中引入了介面從而滿足了OCP,但是在客戶端編碼中需要對工廠類進行例項化。而簡單工廠模式的工廠類是個靜態類,在客戶端無需例項化,這無疑是個吸引人的優點。
管理上的難度:這是個關鍵的問題,工廠方法模式管理不易,因為用太多的類。
根據設計理論建議使用工廠方法模式。但實際上,我們一般都用簡單工廠模式。
4、抽象工廠模式
用來生產不同產品族的全部產品。(對於增加新的產品,無能為力;支援增加產品族)
抽象工廠模式是工廠方法模式的升級版本,在有多個業務品種、業務分類時,通過抽象工廠模式產生需要的物件是一種非常好的解決方式。
抽象工廠模式是支援產品族的,對於單個產品就不行了。用UML來表示關係:
程式碼實現:
定義輪胎的產品,分為低端和高階。
public interface Tyre { //定義輪胎的產品族
void revolve();
}
class LuxuryTyre implements Tyre{
@Override
public void revolve() {
System.out.println("旋轉不磨損!");
}
}
class LowTyre implements Tyre{
@Override
public void revolve() {
System.out.println("旋轉磨損嚴重!");
}
}
定義座椅的產品,分為低端和高階。
public interface Seat{ //定義座椅的產品族
void message();
}
class LuxurySeat implements Seat{
@Override
public void message() {
System.out.println("可以自動按摩!");
}
}
class LowSeat implements Seat{
@Override
public void message() {
System.out.println("不能按摩!");
}
}
定義工廠:
public interface CarFactory { //定義工廠介面
Seat createSeat();
Tyre createTyre();
}
class LowCarFactory implements CarFactory{ //定義生產低端產品族的工廠
@Override
public Seat createSeat() {
return new LowSeat();
}
@Override
public Tyre createTyre() {
return new LowTyre();
}
}
class LuxuryCarFactory implements CarFactory{ //生產高階產品族的工廠
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
}
使用:
public class client {
public static void main(String[] args) {
CarFactory factory=new LuxuryCarFactory(); //定義生成高階產品的工廠
Seat seat = factory.createSeat();
seat.message();
Tyre tyre = factory.createTyre();
tyre.revolve();
}
}
總結:
– 簡單工廠模式(靜態工廠模式)
雖然某種程度不符合設計原則,但實際使用最多。
– 工廠方法模式
不修改已有類的前提下,通過增加新的工廠類實現擴充套件。
– 抽象工廠模式
不可以增加產品,可以增加產品族!