JavaSE之面向物件程式設計—抽象類與介面—— 4(工廠設計模式)
工廠設計模式
在java基礎部分要求掌握三種重點設計模式:工廠設計模式、代理設計模式、單例設計模式。
一、工廠設計模式
我們下面先來看看一般情況下的設計:
對於這樣的場景:劉同學準備去買膝上型電腦,她到商場去買衣服,發現有兩個牌子她都特別喜歡,一款是A,一款是B。
根據上面的情景,我們可以將它抽象出來為一個介面進行實現:
//1.工廠設計模式(重點) //沒有模式的情況: //一般是這樣,對於一個共同有的行為就定義為一個介面中的抽象方法;對於含有這種方法的不同種類 //就定義為一個類,這個類去實現介面中的方法,這樣就可以達到我們的效果。 // interface Clothes{ // void printClothes(); // } // class A implements Clothes{ // public void printClothes(){ // System.out.println("這是A款衣服"); // } // } // class B implements Clothes{ // public void printClothes(){ // System.out.println("這是B款衣服"); // } // } // public class Client{ // public void buyClothes(Clothes clothes){ // clothes.printClothes();//實現買衣服 // } // public static void main(String[] args){ // Client client=new Client(); // client.buyClose(new A());//這樣就表示建立了A款衣服的例項,但是我們必須得知道建立物件的過程 // } //那麼問題來了;如果劉同學這時候又看上了另外一款衣服,我們就不得不返回客戶端進行修改了。所以下面我們採用簡單工廠模式進行實現。 //1.簡單工廠模式:專門定義一個類,用來建立其他類的例項,被建立的例項通常都具有共同的父類。 //買一件衣服的例子 // import java.util.Scanner; // interface Clothes{ // public void print(); // } // class A implements Clothes{ // public void print(){ // System.out.println("這是A款衣服"); // } // } // class B implements Clothes{ // public void print(){ // System.out.println("這是B款衣服"); // } // } // //定義一個類來建立物件——》工廠類 // class ClothesFactory{//這個就是生產衣服的工廠,生產衣服由它實現,即是建立物件由它實現, // //我們的客戶不用知道我們衣服的物件怎麼例項化。 // public static Clothes getInstance(String type){ // Clothes clothes=null;//初始化物件 // if(type.equals("A")){//建立物件,開闢空間,返回具體的物件 // return new A(); // }else{ // return new B(); // } // } // } // public class Client { // public void buyClothes(Clothes clothes){ // clothes.print();//可以起到建立物件的作用:最後對應的衣服去呼叫對應的print() // } // public static void main(String[] args){ // Client client=new Client(); // Scanner scanner = new Scanner(System.in); // System.out.println("請輸入您想要的衣服款式:"); // String type=scanner.nextLine(); // Clothes clothes=ClothesFactory.getInstance(type);//通過傳入的型別判斷是否是在所給範圍內的型別 // client.buyClothes(clothes);//這兒傳入的clothes是建立好之後的物件,即是傳入以後得到相應的那個款式的衣服 // } // } //我們來實現一個買電腦的例子 //電腦的型別分為:HP、Lenvoe //電腦的介面 // import java.util.Scanner; // interface Computer{ // public void print();//對於每一個類它的功能是不同的 // } // //HP的電腦 // class HP implements Computer{ // public void print(){ // System.out.println("這是一臺HP電腦"); // } // } // //聯想的電腦 // class Lenvoe implements Computer{ // public void print(){ // System.out.println("這是一臺聯想電腦"); // } // } // //定義一個生產電腦的工廠:根據客戶傳入的型別專門用來建立物件 // class ComputerFactory{ // //定義一個生產物件的方法 // public static Computer printComputer(String type){ // /*error 如果採用以下這種方法就會出現錯誤,因為這樣就沒有了返回語句,所以我們需要用它下面的這種方法 // if(type.equals("HP")){ // return new HP(); // }else if(type.equals("Lenvoe")){ // return new Lenvoe(); // } // */ // Computer computer=null;//初始化了一個物件 // if(type.equals("HP")){ // computer=new HP(); // }else if(type.equals("Lenvoe")){ // computer=new Lenvoe(); // } // return computer;//這樣函式才有返回值 // } // } // public class Client{ // public void buyComputer(Computer computer){ // computer.print(); // } // public static void main(String[] args){ // Client client = new Client(); // Scanner scanner=new Scanner(System.in); // System.out.println("請輸入你想要的型別:"); // String type=scanner.nextLine(); // Computer computer = ComputerFactory.printComputer(type);//靜態方法通過類名呼叫,不用知道具體的工廠類 // client.buyComputer(computer); // } // } 在工廠模式中我們最需要注意的就是,它的思想,通過建立一個類(這個類叫生產工廠)來專門建立我們需要物件,並且在主函式中我們需要 建立一個方法,來對應的呼叫我們建立物件以後這個物件對應的方法。 二、工廠方法模式 工廠方法模式:定義一個用來建立物件的介面,讓子類決定例項化哪個類,讓子類決定例項化延遲到子類。 工廠方法模式是針對每個產品提供一個工廠類,在客戶端中判斷使用哪個工廠類去建立物件。我們將之前的ComputerFactory抽象成一個介面,那麼建立相應具體的工廠類去實現該介面的方法。
//工廠方法模式
// interface Computer{
// void printCOmputer();
// }
// class HP implements Computer{
// public void printCOmputer(){
// System.out.println(“這是HP電腦”);
// }
// }
// class Lenvoe implements Computer(){
// public void printCOmputer(){
// System.out.println(“這是聯想電腦”);
// }
// }
// //定義一個介面的工廠
// interface ComputerFactory{
// Computer createComputer();
// }
// //建立工廠類去實現介面的方法
// //屬於HP的工廠類
// class Ms1Factory implements ComputerFactory{
// public Computer createComputer(){
// return new HP();
// }
// }
// //屬於Lenvoe的工廠類
// class Ms2Factory implements ComputerFactory{
// public Computer createComputer(){
// return new Lenvoe();
// }
// }
// //不同的工廠類建立自己的物件
// public class Client{
// public void buyComputer(Computer computer){
// computer.printComputer();
// }
// public static void main(String[] args){
// Client client=new Client();
// ComputerFactory factory=new Ms2Factory();//實現向上轉型——》父類介面(在這裡就必須得知道具體的工廠類)
// //雖然介面是用來建立物件的,但是我們最後是通過對應的工廠類來建立物件的。
// client.buyComputer(factory.createComputer());
// }
// }
對於簡單工廠模式和工廠方法模式的對比:
(1)對於簡單工廠模式,建立物件的邏輯判斷放在了工廠類中,客戶不知道具體的類,不知道具體建立物件的方式,但是違背了開閉原則,如果需要新增加具體的類,就必須修改工廠類。
(2)對於工廠方法模式而言,是通過擴充套件來新增加具體類的,複合開閉原則,但是客戶端就必須知道具體的工廠類,也就是將邏輯判斷由簡單工廠的工廠類挪到了客戶端。
(3)工廠方法橫向擴充套件很方便,加入新增加了一種產品,那麼只需要新增加一個相應的工廠類和產品類去實現抽象工廠介面和抽象產品介面即可,不用修改原始碼。
優點:
降低了程式碼的耦合度,物件的生成交給子類完成;
實現了開閉原則,每次增加子產品不需要修改原始碼
缺點:
增加了程式碼量,每個具體的產品都需要一個具體的工廠方法。
當增加一個抽象產品的時候就需要修改工廠了。
三、抽象工廠模式
概要:
(1)多個抽象產品
(2)具體產品類
(3)抽象工廠類 —宣告(一組)返回抽象產品的方法
(4)具體工廠類 —生成(一組)具體產品
抽象工廠模式:提供一個建立一系列相關或相互依賴物件的介面,不需要具體指定它們的類。
抽象工廠模式與工廠方法模式基本相似,工廠方法模式是抽象工廠模式的一種特殊情況,當工廠只生產一個產品的時候,就為工廠方法模式;而工廠生產兩個或者兩個以上的產品時就為抽象工廠模式。
//抽象工廠模式
interface Computer {
void printComputer();
}
class AComputer implements Computer{
public void printComputer(){
System.out.println(“這是A類電腦”);
}
}
class BComputer implements Computer{
public void printComputer(){
System.out.println(“這是B類電腦”);
}
}
//定義一個介面來建立不同型別電腦的作業系統
interface OperatingSystem{
void printSystem();
}
//對於兩類不同的電腦都有各自的作業系統的類
class ASystem implements OperatingSystem{
public void printSystem(){
System.out.println(“這是A類作業系統”);
}
}
class BSystem implements OperatingSystem{
public void printSystem(){
System.out.println(“這是B類作業系統”);
}
}
//定義一個生產工廠的介面
interface ProductionFactory{
//抽象工廠模式,就是在這個地方與工廠模式有區別,它的這個建立類的介面中有多個抽象方法
//去建立不同種類的物件。
Computer createComputer();//這個抽象方法是為了建立不同的物件的
OperatingSystem createSystem();//這個抽象方法是為了建立不同的作業系統的
}
//還是和工廠模式一樣的,每個種類都有自己的生產工廠
class AFactory implements ProductionFactory{
public Computer createComputer(){
return new AComputer();
}
public OperatingSystem createSystem(){
return new ASystem();
}
}
class BFactory implements ProductionFactory{
public Computer createComputer(){
return new BComputer();
}
public OperatingSystem createSystem(){
return new BSystem();
}
}
//客戶
public class Client{
//這個是具體建立電腦物件的
public void buyComputer(Computer computer){
computer.printComputer();
}
//這個是具體建立作業系統的物件的
public void use(OperatingSystem s){
s.printSystem();
}
public static void main(String[] args){
Client client=new Client();
//先開闢一個生產工廠
ProductionFactory factory=new AFactory();
Computer computer=factory.createComputer();
OperatingSystem system=factory.createSystem();
client.buyComputer(computer);
client.use(system);
}
}
對於以上三種模式總結:
簡單工廠模式最大的優點就是:在工廠類中公有具體的邏輯去判斷生產什麼產品,將類的例項化交給了工廠,客戶不需要知道具體的例項化。
工廠方法模式最大的優點在於:在工廠方法模式中我們遵循了開閉原則,當我們需要新增加一種產品的時候我們不需要修改之前的類,只需要增加一個類去實現介面就可以了,但是它將之前簡單工廠模式中在類中判斷的邏輯思想交給了客戶,需要我們的客戶去判斷。
抽象工廠模式進一步擴充套件了我們的工廠方法模式,在抽象方法模式裡面我們可以新增一類新產品,它遵循了OCP原則。