程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 為什麼要用設計模式?先看看6大原則,要用設計模式原則

為什麼要用設計模式?先看看6大原則,要用設計模式原則

編輯:JAVA綜合教程

為什麼要用設計模式?先看看6大原則,要用設計模式原則


  引言                                       

  本人不怎麼喜歡看書, 因為我看書一目十行, 看了就忘, 所以我這邊一邊看左老師的, 一邊抄, 增加自己的記憶力

  這是左老哥的 http://www.cnblogs.com/zuoxiaolong/p/pattern1.html

  直接進入正題, 相信大家入了這一行, 幾乎都忙的一筆, 但還是想要在閒時充下電. 我老想給自己充電, 時間也不少, 但是呢, 不玩上兩把游戲不過瘾, 讓大腦休息休息, 但是一玩游戲就停不下來了, 要是我把玩游戲的精神來學習java, 這句話怎麼這麼耳熟, 不管了, 先讀一讀設計模式. 

  ps 上面都是扯淡

  學習設計模式, 就是為了讓我們顯著更加專業, 是的, 我們是專業coder

  主體

  學習設計模式之前, 我們需要先了解六大原則, 這原則看著很有道理

①單一原則:

    意思: 只做一件事.

    我用個偽代碼表達一下

//計算文件中的
class Calculator {
   //相加  
  public int add() throws NumberFormatException, IOException{ File file = new File("E:/data.txt"); BufferedReader br = new BufferedReader(new FileReader(file)); int a = Integer.valueOf(br.readLine()); int b = Integer.valueOf(br.readLine()); return a+b; }
 }

    要是誰封裝了這麼一個類, 然後你用了, 臥槽什麼怎麼只有加法, 沒有減法 乘法, 你然後是不是要 copy 一下 ,把+ 號改為其他符號 . 

    q:這個類中哪裡違反了單一原則呢?

    梳理一下, 我們用這個計算類是為什麼干什麼, 計算文本中的和

    引申一下, 實際的操作步驟:

                 ① 獲取文件內容

                 ② 計算返回值        

    這個類同時擁有兩個職責

    q:這個類還存在什麼問題?

    在開發初期, 我們很有可能為了快速, 進行大量的copy, 這樣就導致了很多的代碼重復, 這樣可能我們為了書寫一個相減或相乘的方法, 來copy 加法中的代碼進行修改

  下面我們需要把上面的代碼修改一下

//獲取文件內容類
class Reader{

    int a,b;

    public Reader(String path)throws Exception{
     
    BufferedReader br = new BufferedReader(new FileReader(new File(path)));
      a= Integer.valueOf(br.readLine);          
      b= Integer.valueOf(br.readLine);          
    }
    
    int getA(){
        return a;
    }

         
    int getB(){
        return b;
    }  
}

//單獨的計算類

class Calculator{
    
    int add(int , int b){
    return a+b;
}    

    int subtract(int , int b){
    return a-b;
}        
}

    這樣簡單明朗,意思深刻 ,當然這些都是我抄的大神的, 有時候沒有必要自己寫一些代碼, 跟著前輩走, 帶你少走很多彎路, 有時候總是走自己的路, 盡管得到的更多, 但是並不是每個人都是這樣的, 我是前者, 我明白自己的短板. 

    

②裡氏替換原則

   意思: 子類應該可以替換掉父類並且正常工作

     子類一般不該重寫父類的方法, 因為父類的方法一般都是對外公開的.

   但是在實際開發當中, 我們可能為了便利, 經常重寫父類的方法, 這樣就導致的子類和父類作了不同的功能,

   下面我們用代碼來描述一下:

//父類
class FatherClass{

    public void eat(){
     System.out.println("我愛吃米飯");

    }  


}
 
//子類
class SonClass extends FatherClass{ void eat(){ System.out.println("我不愛吃米飯"); } } class SomeoneClass { @Test public void runLiSi(){ FatherClass fc = new FatherClass(); SonClass sc = new SonClass(); fc.eat(); sc.eat(); } }

    上面這個例子, 父類和子類做同樣的事, 但是結果確實相反的

    這個原則是在約束我們, 往往出現這種情況的時候, 我們需要考慮一下能不能, 效果如何. 

 

③接口隔離原則(接口最小化原則) 

   開發中中 我們經常發現 我們在實現一個接口的同時, 有很多方法都是空的

    直接上代碼

 

//手機接口
public interface BaseMobile {
    
       public void call();//打電話

       public void sendSms();//發短信

       public void playBird();//玩游戲  
}

 

      只要是手機那就應該有打電話發短信的功能, 但是玩游戲的功能並不一定是每個手機都有的

          所以我們可以先讓去掉 玩游戲 這個接口 最小化這個接口

//修改後的代碼

public interface BaseMobile {
    
    public void call();

    public void sendSms();  

}

//適配器

public interface IOSMobile extends BaseMobile{

    public void playBird();

}

     這樣, 就很清晰的理解接口最小化原則,

     但是凡事都有特例,

     不需要發短信功能的手機存在嗎, 很顯然存在啊. 同樣的, 時代發展的很快, 手機的基本功能也在變遷, 就像這樣是個手機應該就能上網之類的功能

     ps:寫到這裡, 我明顯感覺我的思考問題的方式在發生著改變, 我們的代碼, 應該遵循的一些規范, 往往在人們的生活方式改變的同時改變著, 代碼離不開生活, 美好的生活由代碼構成, 在今後的社會, 有可能我們的代碼就像是科學一樣, 人人都應該了解她, 學習她. 

 

④依賴倒置原則    

    高層模塊不應該依賴與底層模塊, 二者都應該依賴於抽象, 抽象不應該依賴於細節, 細節應該依賴於抽象

    這句話意思就是, 不管你是北京人,還是北京朝陽群眾, 你都是中國人, 這麼理解就沒錯了. 實際上, 我還是感覺上句話好理解一點.

    下面我們直接用代碼來表示一下

 

//抽象 人
public interface People{
    
    void myInfo();//自我介紹
    void canDo();//能做什麼
}

//中國人 
public class China:People{
    public void myInfo(){
      System.out.println("我是中國人");  
  }
    void canDo(){
     System.out.println("我會code,搬磚,修車,開車,滑稽");  
}
}   

//美國人
public class America:People{
    public void myInfo(){
      System.out.println("我是美國人");  
  }
    void canDo(){
     System.out.println("我會code,mygod,yea,aye,huhuh");  
}
}   
//高層 
public class PeopleInfo{

private People people;

public PeopleInfo(People people){
    this.people =people;
}
 public void myInfo(){
      people.myInfo();
  }
    void canDo(){
     people.canDo();
}

}

 

  現在PeopleInfo這個類依賴於People, 而具體方法不會影響PeopleInfo , 只要改變實現People即可 ,也就是細節依賴於抽象

  並且 PeopleInfo 不依賴於China和America, 也就是依賴關系被倒置了

  這裡我解釋下可能有的同學不是很清楚其中的利害   依賴倒置

  PeopleInfo 依賴於 People  ,當我們需要使用PeopleInfo做某些事情的時候, 這時需要注入China或其他實現類, 但是PeopleInfo並不依賴China,

PeopleInfo只依賴People .

  想象一下, 我們使用PeopleInfo, 注入China,使用myInfo()的結果:我是china. 注入America,使用myInfo()的結果:我是America. 

      q:說明PeopleInfo不依賴 China 和America ,但是怎麼能調用它們的方法呢?

  反過來想下, 我想要使用China myInfo()方法 有兩個方法

         第一種 直接new 是不是有點粗暴

         第二種 把China 注入PeopleInfo  專業code啊

     第二種 China反而依賴於PeopleInfo 依賴就這麼反轉了, 這是我目前的理解,有問題, 大家可以指出來

 

 

⑤迪米特原則

    最小知道原則, 一個類盡量不應該知道其他類太多的東西,不要有太多的接觸

    大白話, 就是一個類不應該依賴其他的類太多細節, 其他類不應該對外提供太多細節, 要高內聚, 低耦合

先來個不符合這個原則的

 

//低內聚
public class LowCohesion{

   private String name;

   private int age;

   private boolean openMouth = false;
    
   public LowCohesion(String name, int age){

           this.name = name;
           this.age = age;
  }

    
  public void setOpenMouth(boolean boo){

     this.openMouth = boo;
 }
  public saySelf(){
     if(openMouth){
        System.out.println("大家好,我叫"+name+", 今年"+age+"了");
    }else{
        System.out.println("......");
    }
     
 }

}

//客戶端

public class client{

       public static void main(String[] args) throws Exception {
        LowCohesion lc= new LowCohesion("老哥",26);//來了個老哥
        lc.setOpenMouth(true);//老哥張嘴
        lc.saySelf();//老哥說話
     
    }

}

 

    假設我們是面試官, 來個人,我們一般只需要讓人自我介紹 , 也就是 saySelf ,這個例子裡面我們需要openMouth,這就是 類不應該依賴其他的類太多細節

 

    這個動作可以是外驅的 但是這個細節完全沒必要暴露出去, 我們要的是自我介紹, 而不是 先我准許你說話 , 然後你可以自我介紹, saySelf這個動作應該內置 openMouth ,   也就是 其他類不應該對外提供太多細節

    我的表達可能不是很准確, 迪米特原則,我的理解是雙向約束的規則, 其中主要是針對 類的內聚性

⑥開閉原則 

    對修改關閉, 對擴展開發.

    在實際開發中, 我們由於各種場景需求, 需要修改大量的原有的代碼, 很多項目都是非常的趕, 擴展性, 項目有二開就有擴展性

    有時候我感覺自己可以掌控一方, 但是實際真的什麼都不懂, 再次感覺前輩們, 我會堅持下去

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved