小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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)

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

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

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

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

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

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

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

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

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

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

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


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


1.策略模式(Strategy Pattern)


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

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

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


妙計模板:


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é)論:

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


2.代理模式(Proxy Pattern)


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

我們假設(shè)一個場景:梁山伯看上了祝英臺,他就請媒婆去祝英臺家提親;前提是媒婆得知道梁山伯有什么沒有什么吧,不然祝英臺他們家要彩禮,梁山伯拿不出來咋整,所以梁山伯和媒婆要實(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() {
       //默認(rèn)無參構(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é)論:看似媒人在做,其實(shí)是梁山伯的想法。

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

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

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

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

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

 

3.單例模式(Singleton Pattern)


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

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

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

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

 

我們假設(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é)果:



像這樣毫無線程安全保護(hù)的類,如果我們把它放入多線程的環(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)兩個實(shí)例了?如果在程序中出現(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('唐玄宗');
   }
}


以上代碼也可以這樣實(shí)現(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、單例模式理解起來簡單,但是具體實(shí)現(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ā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多