在開發系統中,常常會碰到一個問題。如今須要實現的一些功能,可是這個功能模塊之後必定是須要擴展的,那麼如今開發中就不只要實現如今的功能,還要考慮之後的擴展。那麼爲了系統的健壯,擴展就要遵循開閉原則(簡單說,就是對修改關閉,對擴展開發)。設計模式
要實現這個功能,就是要找到一種方法。能夠建立一些操做,可是如今不實現,等着之後來實現這個功能。框架
如今經過一我的成長過程當中學到的技能來展現一下這種方案:ide
在社會中生存技能千千萬萬,人也是在不斷學習技能的,可是都能學習到那些技能本身也不能肯定。可是學習技能是必定的。這時候咱們就先定義一個技能的類,可是不知道學習的是什麼技能,因此就先實現一個技能接口。學習
package designPattern_3_FactoryMethod; //技能接口 public interface ILifeKills { public void kill(); }
學習的過程不要和技能耦合在一塊兒,須要單獨對象來實現,學習的過程就是建立技能對象的過程,因此這個學習對象就是用來生成具體的技能對象的。可是若是是一我的生學習技能方面的框架的話,確定也不知道學習的是什麼技能,那這就是自相矛盾了。怎麼辦呢?既然是框架,確定有人來具體實現這個須要學習的技能和具體的學習方式。因此這個咱們就知識定義學習方法,可是不定義學習的具體內容,讓使用框架的人來實現。這就是定義一個抽象類。spa
package designPattern_3_FactoryMethod; //抽象學習方法 public abstract class AbstractLearn { public void learn(){ ILifeKills lifekill = factoryMethod();
lifekill.kill(); } protected abstract ILifeKills factoryMethod(); }
下面列出交流、開車的技能設計
1 package designPattern_3_FactoryMethod; 2 //交流技能 3 public class Talking implements ILifeKills { 4 public void kill(){ 5 System.out.println("交談技能"); 6 } 7 }
package designPattern_3_FactoryMethod; //開車技術 public class Driver implements ILifeKills { @Override public void kill() { // TODO Auto-generated method stub System.out.println("開車技術!"); } }
具體學習的方法code
package designPattern_3_FactoryMethod; //學習交流的對象 public class LearnTalking extends AbstractLearn { public ILifeKills learn(){ return new Talking(); } }
package designPattern_3_FactoryMethod; //學習開車 public class LearnDriver extends AbstractLearn { @Override protected ILifeKills factoryMethod() { // TODO Auto-generated method stub return new Driver(); } }
客戶端調用對象
1 package designPattern_3_FactoryMethod; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 AbstractLearn al = new LearnTalking(); 7 al.learn(); 8 AbstractLearn al2 = new LearnDriver(); 9 al2.learn(); 10 } 11 }
這面展現的例子就是工廠方法模式。只是我只生產一個具體的對象。之後根據須要能夠生成對應的技能對象。接下來先看下工廠模式的定義,再結合簡單工廠模式分析。結構圖blog
定義一個建立產品對象的工廠接口,將實際建立工做推遲到子類當中。核心工廠類再也不負責產品的建立,這樣核心類成爲一個抽象工廠角色,僅負責具體工廠子類必須實現的接口,這樣進一步抽象化的好處是使得工廠方法模式可使系統在不修改具體工廠角色的狀況下引進新的產品。接口
工廠方法的意義,在父類不知道須要生產具體對象的狀況下,可以完成自身的功能調用,具體的實現延遲到其子類,實際上就是工廠類也抽象化了,具體的對象在各自的工廠子類中來實現。
經過定義能夠看出:抽象出來具體對象的接口,同時把工廠類也抽象化,這樣產品對象和具體工廠都實現各自的抽象類,之後在擴展具體的對象的時候不用修改原來的工廠類,這也更加符合開閉原則。同時也看出來了,工廠方法模式是簡單工廠模式的衍生。若是把工廠類的抽象類省略到,用普通類選擇實現,那麼工廠方法模式就回來到簡單工廠模式。
在使用工廠方法的時候要具備靈活性,在一個具體的工廠功法裏面能夠有多個不一樣的工廠方法,也能夠在一個工廠類中實現十分相近的產品。看着有點相似簡單工廠了,可是本質上仍是工廠方法的本質。只是形式有些變化而已,可是這不重要。就像學習武功,只要內功深厚,不少招式都可以靈活運用,看似神奇,其實都是內功支撐。而設計模式也是如此。工廠方法模式只要把具體對象的實現延遲到子類,之後擴展工廠時候不用再去修改原來的工廠類,符合了開閉原則。那麼就抓住了工廠方法模式的本質。
分析了這麼多工廠模式的優勢,它固然也有缺點。就是會加大代碼的複雜度,若是在不合適的場景中用到頗有可能得不償失。
工廠方法的本質:就是把對象的實現延遲到其子類來實現,使得對產品的擴展更加靈活。這也是工廠方法模式和簡單公共的區別。
工廠方法不是不能夠選擇實現。以個人理解,在一個具體的工廠類中,能夠實現相近的產品。之後擴展的時候再派生另外的類就能夠了。
下一篇分析抽象工廠模式