撩妹祕籍竟是使用設計模式的抽象工廠模式

引入:可以跳過

如果存在一部撩妹的手機,加上一個後宮,請問你該怎麼做?
砸了手機,跟老婆孩子好好過日子,本篇文章到此結束!

我們強行分析一波,假設存在一位叫做志強的男主(沒有在含沙射影)沒有砸掉手機,首先每個姑娘都會有名字,防止太多認錯了。
我們把維繫關係簡單的分成:曖昧–閒聊–約(當然是逛商場啦,別想太多) 對於不同的妹子,肯定採用了不同的曖昧,閒聊,約的方式來俘獲他麼芳心。
如果重構志強與後宮的關係,那麼你會發現志強的撩妹方式,直接和名字掛鉤,對於每一位姑娘的曖昧–閒聊–約可以看作是一個產品族。志強在某一時刻可以同時存在多個姑娘,但是在某一時刻只能消費一位姑娘(指的逛商場,且不包含多人運動的情況),那麼也就是說志強在某一時刻只消費某一產品族。這就是赤裸裸的抽象工廠模式!

我們以一臺計算機主機爲例,機箱,主板,cpu,內存條,顯卡,硬盤是構成一臺主機的組成部分,這裏我們有Dell一套,華碩一套,惠普一套,那麼每一套就是產品族,因爲他們包含了所有組成的他們的產品種類,這就是抽象工廠模式。(打錢!!!)
在這裏插入圖片描述

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創建其他工廠。該超級工廠又稱爲其他工廠的工廠。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。

在抽象工廠模式中,接口是負責創建一個相關對象的工廠,不需要顯式指定它們的類。每個生成的工廠都能按照工廠模式提供對象。

意圖:

提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

主要解決:

主要解決接口選擇的問題。

何時使用:
  • 希望一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節時。
  • 一個系統有多於一個的產品族,而系統只消費其中某一產品族
角色:
  • 抽象工廠(Abstract Factory)角色:
    擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。

  • 具體工廠(Concrete Factory)角色:
    這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對
    象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的

  • 抽象產品(Abstract Product)角色:
    擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。

  • 具體產品(Concrete Product)角色:
    抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。
    這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。
    在這裏插入圖片描述
    廠商看到打錢!😂

與工廠模式的區別:
  • AbstractFactory模式是爲創建一組(有多類)相關或依賴的對象提供創建接口
  • Factory模式是爲一類對象提供創建接口
優缺點:

“開放-封閉”原則要求系統對擴展開放,對修改封閉。通過擴展達到增強其功能的目的。對於涉及到多個產品族與多個產品等級結構的系統,其功能增加包括兩方面:

  • 增加產品族:Abstract Factory很好的支持了"開放-封閉開放-封閉"原則

  • 增加新產品的等級結構:需要修改所有的工廠角色,沒有很好支持“開放-封閉”原則。

  • 綜合起來,抽象工廠模式以一種傾斜的方式支持增加新的產品,它爲新產品族的增加提供方便,而不能爲新的產品等級結構的增加提供這樣的方便。

當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。

產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。

解決方案: 反射

UML圖

在這裏插入圖片描述

實現

UML類似上面的,在重新給出一遍。
在這裏插入圖片描述
IProductA

package AbstractFactory;
public interface IProductA {
    //每個產品共有的方法
    public void shareMethod();

    // 每個產品相同方法,不同實現
    public  void doSomething();
} 

IProductB

package AbstractFactory;
public interface IProductB {
    //每個產品共有的方法
    public void shareMethod()  ;

    // 每個產品相同方法,不同實現
    public void doSomething();
}
 

ProductA1

package AbstractFactory;
public class ProductA1 implements IProductA {
    public void doSomething() {
        System.out.println("我是產品A1");
    }

	@Override
	public void shareMethod() {
		// TODO Auto-generated method stub
		
	}
}

ProductA2

package AbstractFactory;
public class ProductA2 implements IProductA {
    public void doSomething() {
        System.out.println("我是產品A2");
    }

	@Override
	public void shareMethod() {
		// TODO Auto-generated method stub
		
	}
}

ProductB1

package AbstractFactory;
public class ProductB1 implements IProductB {
    public void doSomething() {
        System.out.println("我是產品B1");
    }

	@Override
	public void shareMethod() {
		// TODO Auto-generated method stub
		
	}
}

ProductB2

 package AbstractFactory;
public class ProductB2 implements IProductB {
    public void doSomething() {
        System.out.println("我是產品B2");
    }

	@Override
	public void shareMethod() {
		// TODO Auto-generated method stub
		
	}
} 

ICreator

package AbstractFactory;
public interface ICreator {
    //創建A產品
    public   IProductA createProductA();

    //創建B產品
    public  IProductB createProductB();
} 

Creator1

package AbstractFactory;
public class Creator1 implements ICreator {
    public IProductA createProductA() {
        return new ProductA1();
    }

    public IProductB createProductB() {
        return new ProductB1();
    }
}

Creator2

package AbstractFactory;
public class Creator2 implements ICreator {
    public IProductA createProductA() {
        return new ProductA2();
    }

    public IProductB createProductB() {
        return new ProductB2();
    }
}

Client

package AbstractFactory;

public class Client {
    public static void main(String[] args) {
        //定義出兩個工廠
        ICreator creator1 = new Creator1();
        ICreator creator2 = new Creator2();
        //產生A1對象
        IProductA a1 = creator1.createProductA();
        //產生A2對象
        IProductA a2 = creator2.createProductA();
        //產生B1對象
        IProductB b1 = creator1.createProductB();
        //產生B2對象
        IProductB b2 = creator2.createProductB();
        a1.doSomething();
        a2.doSomething();
        b1.doSomething();
        b2.doSomething();
    }
}

運行結果
在這裏插入圖片描述
在這裏插入圖片描述

!!!使用反射加配置文件解耦實現上述過程

去掉所有Creator相關,其餘不變。
加上以下內容:

package AbstractFactory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;

 

public class Reflect_Creator {
	private static String Type = null;
	public  void init() {
		Properties pro = new Properties();
		ClassLoader classLoader = DataAccess.class.getClassLoader();
		InputStream is = classLoader.getResourceAsStream("DataBaseSetting.properties");
		try {
			pro.load(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("初始化失敗,請檢查配置文件");
		}
		Type = pro.getProperty("Type");
	}
    public  IProductA createProductA() throws Exception {
    	Class<?> cls = Class.forName(Type+"1");
		Constructor<?> cs=cls.getConstructor( );
		Object re= cs.newInstance(); 
		return (IProductA) re;
    }

    //創建B產品
    public  IProductB createProductB() throws Exception {
    	Class<?> cls = Class.forName(Type+"2");
		Constructor<?> cs=cls.getConstructor( );
		Object re= cs.newInstance(); 
		return  (IProductB) re;
    }
}  
package AbstractFactory;

public class Client {
    public static void main(String[] args) throws Exception {
       Reflect_Creator.init();
       IProductA A1=Reflect_Creator.createProductA();
       IProductB B1=Reflect_Creator.createProductB();
    }
}

老有人私信我,說我博客表情包花裏胡哨的,我想說,我不放表情包,部分小夥伴不一定能看完整篇文章,以後會減少出現,但一定不會缺席。😂

寫在最後:
我叫風骨散人,名字的意思是我多想可以不低頭的自由生活,可現實卻不是這樣。家境貧寒,總得向這個世界低頭,所以我一直在奮鬥,想改變我的命運給親人好的生活,希望同樣被生活綁架的你可以通過自己的努力改變現狀,深知成年人的世界裏沒有容易二字。目前是一名在校大學生,預計考研,熱愛編程,熱愛技術,喜歡分享,知識無界,希望我的分享可以幫到你!
如果有什麼想看的,可以私信我,如果在能力範圍內,我會發布相應的博文!
感謝大家的閱讀!😘你的點贊、收藏、關注是對我最大的鼓勵!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章