乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      23種設(shè)計模式詳解(一)

       太極混元天尊 2018-05-03


      首先,了解23種設(shè)計模式的基本概念。

      Java的設(shè)計模式三大類

      創(chuàng)建型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。

      結(jié)構(gòu)型模式(7種):適配器模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。

      行為型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問者模式、中介者模式、解釋器模式。


      設(shè)計模式遵循的原則有6個

      1、開閉原則(Open Close Principle)

          對擴展開放,對修改關(guān)閉。

      2、里氏代換原則(Liskov Substitution Principle)

          只有當(dāng)衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被復(fù)用,而衍生類也能夠在基類的基礎(chǔ)上增加新的行為。

      3、依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)

          這個是開閉原則的基礎(chǔ),對接口編程,依賴于抽象而不依賴于具體。

      4、接口隔離原則(Interface Segregation Principle)

          使用多個隔離的借口來降低耦合度。

      5、迪米特法則(最少知道原則)(Demeter Principle)

          一個實體應(yīng)當(dāng)盡量少的與其他實體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對獨立。

      6、合成復(fù)用原則(Composite Reuse Principle)

          原則是盡量使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。


      接下來,23種設(shè)計模式詳解開始。


      1.策略模式(Strategy Pattern)


      策略模式定義了一系列算法,并將每個算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。

      相互替換:也就是說它們具有共性,而它們的共性就體現(xiàn)在策略接口的行為上,另外為了達到最后一句話的目的,也就是說讓算法獨立于使用它的客戶而獨立變化,我們需要讓客戶端依賴于策略接口。

      我們先定義一個場景:?劉備去江東娶媳婦,走之前諸葛亮給趙云(伴郎)了一個錦囊,里面有三個妙計,這三個妙計能幫劉備順利取上媳婦。


      妙計模板:


      public interface Strategy {
         public void operate();
      }


      A妙計:


      public class AStrategy implements Strategy{
         @Override
         public void operate() {
             System.out.println('找喬國老幫忙,讓吳國太給孫權(quán)施加壓力');

         }
      }


      B妙計:


      public class BStrategy implements Strategy{
         @Override
         public void operate() {
             System.out.println('求吳國太開個綠燈,放行');

         }
      }


      C妙計:


      public class CStrategy implements Strategy{
         @Override
         public void operate() {
             System.out.println('孫夫人斷后,擋住追兵');

         }
      }


      裝妙計的錦囊即策略的應(yīng)用場景:


      public class Kit {

         private Strategy straegy;
         //構(gòu)造函數(shù),你要使用那個妙計
         public Kit(Strategy straegy) {
             this.straegy = straegy;
         }
         //使用計謀
         public void operate(){
             this.straegy.operate();
         }
      }


      使用者趙云:


      public class zhaoYun {

         public static void main(String[] args){
             Kit kit;
             //使用第一個妙計
             kit=new Kit(new AStrategy());
             kit.operate();
             //使用第二個妙計
             kit=new Kit(new BStrategy());
             kit.operate();
             //使用第三個妙計
             kit=new Kit(new CStrategy());
             kit.operate();
         }
      }


      結(jié)果:



      結(jié)論:

      策略模式的第一個特點就是擴展性,即OCP,可以繼續(xù)增加,只要修改應(yīng)用場景即可;其次,策略模式?jīng)Q定權(quán)在用戶,系統(tǒng)本身提供不同方法的實現(xiàn),對各種方法做封裝。因此,策略模式多用在算法決策系統(tǒng)中,外部用戶只需要決定用哪個算法即可。


      2.代理模式(Proxy Pattern)


      代理模式就是多一個代理類出來,替原對象進行一些操作,比如我們在租房子的時候回去找中介,為什么呢?因為你對該地區(qū)房屋的信息掌握的不夠全面,希望找一個更熟悉的人去幫你做,此處的代理就是這個意思。再如我們有的時候打官司,我們需要請律師,因為律師在法律方面有專長,可以替我們進行操作,表達我們的想法。

      我們假設(shè)一個場景:梁山伯看上了祝英臺,他就請媒婆去祝英臺家提親;前提是媒婆得知道梁山伯有什么沒有什么吧,不然祝英臺他們家要彩禮,梁山伯拿不出來咋整,所以梁山伯和媒婆要實現(xiàn)同一個接口(familyStatus);


      public interface familyStatus {
         public void marriagePropose();
      }


      梁山伯:


      public class liangShanBo implements familyStatus {
         @Override
         public void marriagePropose() {
             System.out.print('我想娶英臺');
         }
      }


      媒婆:


      public class Matchmaker implements familyStatus{
         private familyStatus familyStatus;

         public Matchmaker() {
             //默認無參構(gòu)造是梁山伯的代理
             this.familyStatus = new liangShanBo();
         }

         public Matchmaker(familyStatus familyStatus) {
             //也可以是任何人的代理
             this.familyStatus = familyStatus;
         }

         @Override
         public void marriagePropose() {
             this.familyStatus.marriagePropose();
         }
      }


      祝英臺:


      public class zhuYingtai {
         public static void main(String[] args){
             Matchmaker mm=new Matchmaker();
             mm.marriagePropose();
         }
      }


      結(jié)果:




      結(jié)論:看似媒人在做,其實是梁山伯的想法。

      代理模式主要實現(xiàn)了Java的多態(tài),干活的是被代理類,代理類主要是跑腿。那怎么能知道被代理類能不能干活,簡單,同根就成,實現(xiàn)同一個接口,大家知根知底,你能做啥我清楚的很。

      在開發(fā)過程中,如果已有的方法在使用的時候需要對原有的方法進行改進,此時有兩種辦法:

      1、修改原有的方法來適應(yīng)。這樣違反了“對擴展開放,對修改關(guān)閉”的原則。

      2、就是采用一個代理類調(diào)用原有的方法,且對產(chǎn)生的結(jié)果進行控制。這種方法就是代理模式。

      使用代理模式,可以將功能劃分的更加清晰,有助于后期維護!

       

      3.單例模式(Singleton Pattern)


      單例對象(Singleton)是一種常用的設(shè)計模式。在Java應(yīng)用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處:

      1、某些類創(chuàng)建比較頻繁,對于一些大型的對象,這是一筆很大的系統(tǒng)開銷。

      2、省去了new操作符,降低了系統(tǒng)內(nèi)存的使用頻率,減輕GC壓力。

      3、有些類如交易所的核心交易引擎,控制著交易流程,如果該類可以創(chuàng)建多個的話,系統(tǒng)完全亂了。(比如一個軍隊出現(xiàn)了多個司令員同時指揮,肯定會亂成一團),所以只有使用單例模式,才能保證核心交易服務(wù)器獨立控制整個流程。

       

      我們假設(shè)一個場景:大臣參拜皇帝,今天肯定只有一個皇帝,明天也肯定只有一個皇帝,皇帝絕對不可能出現(xiàn)兩個,這就是妥妥的單例模式。

      皇帝:


      public class Emperor {
         //先定義一個皇帝放在這兒
         private static Emperor emperor=null;

         public Emperor() {
             //世俗和道德約束,不產(chǎn)生第二個皇帝
         }
         public static Emperor getInstance(){
             //如果沒有定義皇帝,定義一個
             if (emperor==null){
                 emperor=new Emperor();
             }
             return emperor;
         }
         public static void EmperorInfo(){
             //皇帝是誰
             System.out.println('唐玄宗');
         }
      }


      大臣:


      public class Minister {
         public static void main(String[] args){
             Emperor emperor1= Emperor.getInstance();
             //昨天的皇帝是誰
             emperor1.EmperorInfo();
             Emperor emperor2= Emperor.getInstance();
             //今天的皇帝是誰
             emperor2.EmperorInfo();
         }
      }


      結(jié)果:



      像這樣毫無線程安全保護的類,如果我們把它放入多線程的環(huán)境下,肯定就會出現(xiàn)問題了,如何解決?我們先寫一個通用的單例程序分析一下:


      public class Emperor {
         //先定義一個皇帝放在這兒
         private static Emperor emperor=null;

         public Emperor() {
             //世俗和道德約束,不產(chǎn)生第二個皇帝
         }
         public Emperor getInstance(){
             //如果沒有定義皇帝,定義一個
             if (this.emperor==null){
                 this.emperor=new Emperor();
             }
             return this.emperor;
         }
         public static void EmperorInfo(){
             //皇帝是誰
             System.out.println('唐玄宗');
         }
      }


      假如現(xiàn)在兩個線程A.B,A執(zhí)行到this.emperor=new Emperor()正在申請內(nèi)存分配,這時候B執(zhí)行到了if (this.emperor==null),這時候是true還是false?如果是true,線程往下走,是不是就出現(xiàn)兩個實例了?如果在程序中出現(xiàn)這樣的問題會如何呢?最可怕的是你覺得代碼并沒問題,這是最可怕的;怎么解決呢?最簡單的一種解決方式:

      直接new一個對象傳遞給類的成員變量,用的時候getInstance()直接給你返回來:


      public class Emperor {
         //先定義一個皇帝放在這兒
         private static final Emperor emperor=new Emperor();

         public Emperor() {
             //世俗和道德約束,不產(chǎn)生第二個皇帝
         }
         public synchronized static Emperor getInstance(){
             return emperor;
         }
         public static void EmperorInfo(){
             //皇帝是誰
             System.out.println('唐玄宗');
         }
      }


      以上代碼也可以這樣實現(xiàn):


      public class Emperor {
         //先定義一個皇帝放在這兒
         private  static Emperor emperor=null;

         public Emperor() {
             //世俗和道德約束,不產(chǎn)生第二個皇帝
         }
         private static synchronized void syncInit() {
             if(emperor ==null){
                 emperor=new Emperor();
             }
         }

         public static Emperor getInstance(){
             if(emperor==null){
                 syncInit();
             }
             return emperor;
         }
         public static void EmperorInfo(){
             //皇帝是誰
             System.out.println('唐玄宗');
         }
      }


      通過單例模式的學(xué)習(xí)告訴我們:

      1、單例模式理解起來簡單,但是具體實現(xiàn)起來還是有一定的難度。

      2、synchronized關(guān)鍵字鎖定的是對象,在用的時候,一定要在恰當(dāng)?shù)牡胤绞褂茫ㄗ⒁庑枰褂面i的對象和過程,可能有的時候并不是整個對象及整個過程都需要鎖)。


      4.多例模式(Multition Pattern)


      沒上限的多例模式太簡單,和你隨便new沒差別,咱們來一個有上限的;

      歷史上有沒有兩個皇帝過,有!明英宗朱祁鎮(zhèn)和明景帝朱祁鈺,大臣們都懵逼了。

      皇帝:


      public class Emperor {
         //最多兩皇帝
         private static int maxNumOfEmperor=2;
         //皇帝列表
         private static ArrayList EmperorList=new ArrayList(maxNumOfEmperor);
         //皇帝叫什么名字
         private static ArrayList EmperorInfoList=new ArrayList(maxNumOfEmperor);
         //那個皇帝掌著權(quán)
         private static int countOfEmperor=0;
         //先把皇帝產(chǎn)出來
         static{
             for(int i = 0; i
                 EmperorList.add(new Emperor('皇'+(i+1)+'帝'));
             }
         }
         private Emperor(){
             //約束最多兩個皇帝
         }
         private Emperor(String info){
             EmperorInfoList.add(info);
         }
         public static Emperor getInstance(){
             Random random=new Random();
             countOfEmperor=random.nextInt(maxNumOfEmperor);
             return (Emperor) EmperorList.get(countOfEmperor);
         }
         public static void EmperorInfo(){
             //皇帝是誰
             System.out.println(EmperorInfoList.get(countOfEmperor));
         }
      }


      大臣:


      public class Minister {
         public static void main(String[] args){
             //10個大臣
             int ministerNum=10;
             for(int i=0;i10;i++){
                 Emperor emperor= Emperor.getInstance();
                 System.out.print('第'+(i+1)+'個大臣參拜的是:');
                 emperor.EmperorInfo();
             }


         }
      }


      結(jié)果:



      如果就只想拜哪一個皇帝,怎么辦呢?

      getInstance(param);



      源碼:


      鏈接: https://pan.baidu.com/s/1gTjFKuimHnCQ6H9LoBPKSA 

      密碼: v28k





        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多