在講解簡單原廠模式之前,有必要先瞭解一下OO的一些原則
1.OCP(開閉原則,Open-Closed Principle):一個軟體的實體應當對擴充開放,對修改關閉。也就是說,對於一個已有的軟體,如果需要擴充,應當在不需修改
已有代碼的基礎上進行。
2.DIP(依賴倒轉原則,Dependence Inversion Principle):要針對介面編程,不要針對實現編程。簡單點說,對於不同層次的編程,高層次暴露給低層次
的應當只是介面,而不是它的具體類。
3.LoD(迪米特法則,Law of Demeter):只與你直接的朋友通訊,而避免和陌生人通訊。
舉個簡單易懂的例子來學習簡單工廠類:
有一片果園,裡面種植有蘋果和香蕉,有一個商店,從果園中購買了一些蘋果核和香蕉。現在,商店就是用戶端,蘋果和香蕉就是產品,現在商店出售水果,不使用簡單原廠模式來實現的例子如下:
//用戶端類public class Store { public static void main(String[] args) { Apple apple=new Apple(); System.out.print(apple.tell()); Banana banana=new Banana(); System.out.print(banana.tell()); }}//蘋果類class Apple{ public String tell(){ return "我是蘋果"; }}//香蕉類class Banana{ public String tell(){ return "我是香蕉"; }}
從這個例子不難看出,store類是依賴於Apple和Banana類的,也就是說用戶端依賴於產品,
如果果園中沒有蘋果了,商店也就買不到,更別說賣了,Store對該類的執行個體化也要刪除。
總之,就是違背了OCP原則,用戶端直接依賴於產品
每回都需要去new一下,完全把產品類暴露給用戶端
如果使用簡單原廠模式
因為Apple類和Banana類都有相同的tell()方法,所以可以定義一個介面,聲明這個方法;
然後通過定義工廠類,讓用戶端依賴工廠,而不直接依賴產品
public class Store {public static void main(String[] args) { Frute a=Factory.getFrute("apple"); //得到產品對象 if(a!=null) System.out.println(a.tell()); Frute b=Factory.getFrute("banana"); //得到產品對象 if(a!=null) System.out.println(a.tell());}}//工廠類class Factory{//只負責產生對象public static Frute getFrute(String name){if(name.equals("apple")){return new Apple();}else if(name.equals("banana")){return new Banana();}return null;}}interface Frute{public String tell();}//蘋果類class Apple implements Frute{public String tell(){return "我是蘋果";}}//香蕉類class Banana implements Frute{public String tell(){return "我是香蕉";}}
簡單原廠模式有什麼優點呢。如上面的例子,用戶端與產品沒有直接建立聯絡,即調用者沒有直接依賴於被調用這,當Apple類Banana類修改後,不需要對其進行修改
而且Frute介面的使用,體現了DIP原則。
缺點:當對系統進行擴充的時候,比如增加一個Grape類,不需要修改其他產品類,如Apple和banana,貌似符合OCP原則,但實際上還是需要對工廠類進行修改,所以
簡單原廠模式不符合OCP原則。