1. 程式人生 > >設計模式讀書筆記-工廠模式

設計模式讀書筆記-工廠模式

單例模式的學習

  • 優化了效能,節省記憶體開支
  • 單例模式一般沒有介面,比較難以拓展,這也意味著難以測試(沒有mock)
  • 單例模式也有執行緒安全問題(懶漢式可能有執行緒安全問題)
  • 如果實現了cloneable介面,並實現了clone方法,則可以直接通過物件複製的形式創新一個新物件(不用呼叫構造器),所以單例類最好不實現cloneable介面

工廠設計模式

抽象設計工廠模式

定義一個用於建立物件的
介面,讓子類決定例項化哪一個類。工廠方法使一個類的例項化延遲到其子類(工廠是個抽象類,可以有多個工廠實現類,
Creator為抽象建立類,也就是抽象工廠,具體如何建立產品類是由具體的實現工廠
ConcreteCreator完成的)。

Fizaa4.png

工廠模式優點

  • 如一個呼叫者需要一個具體的產品物件,只要知道這個產品的類名(或約束字串)就可以了,不用知道建立物件的艱辛過程,降低模組間的耦合
  • 在增加產品類的情況下,只要適當地修改具體的工廠類或擴充套件一個工廠類,就可以完成“擁抱變化”。
  • 遮蔽產品類,類似的是資料庫中jdbc的使用,切換資料庫只用換個資料庫連結字串

工廠模式的拓展

  • 簡單工廠:不需要多個工廠,只要一個工廠,需需要工廠介面抽象
  • 多個工廠類,每個工廠類負責一種產品的建立
    Fiz0i9.md.png
  • 單例工廠
public class Singleton {
    //不允許通過new產生一個物件
    private Singleton(){
    }
    public void doSomething(){
    //業務處理
    }
}

public class SingletonFactory {
	private static Singleton singleton;
	static {
		try {
			Class cl = Class.forName(Singleton.class.getName());
			// 獲得無參構造
			Constructor constructor = cl.getDeclaredConstructor();
			// 設定無參構造是可訪問的
			constructor.setAccessible(true);
			// 產生一個例項物件
			singleton = (Singleton) constructor.newInstance();
		} catch (Exception e) {
			// 異常處理
		}
	}

	public static Singleton getSingleton() {
		return singleton;
	}
}

  • 有快取的工廠
public class ProductFactory {
	private static final Map<String, Product> prMap = new HashMap();

	public static synchronized Product createProduct(String type) throws Exception {
		Product product = null;
//如果Map中已經有這個物件
		if (prMap.containsKey(type)) {
			product = prMap.get(type);
		} else {
			if (type.equals("Product1")) {
				product = new ConcreteProduct1();
			} else {
				product = new ConcreteProduct2();
			}
//同時把物件放到快取容器中
			prMap.put(type, product);
		}
		return product;
	}
}

抽象工廠模式

互相影響的產品線是一個暗示,可以把產品之間的約束在工廠內部中邏輯實現

抽象工廠模式是工廠方法模式的升級版本,在有多個業務品種、業務分類時,通過抽象工廠模式產生需要的物件是一種非常好的解決方式。
我們來看看抽象工廠的通用原始碼,首先有兩個互相影響的產品線(也叫做產品族),
例如製造汽車的左側門和右側門,這兩個應該是數量相等的——兩個物件之間的約束,
每個型號的車門都是不一樣的,這是產品等級結構約束的,如以下類圖

FFkP3Q.png

容易拓展產品等級,但難以拓展產品線,因為這要在抽象介面中增加方法,變動太大