1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      本文小編為大家詳細(xì)介紹“Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

      為九江等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及九江網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、九江網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

      1 設(shè)計(jì)模式的目的

      編寫軟件過程中,程序員面臨著來自耦合性,內(nèi)聚性以及可維護(hù)性,可擴(kuò)展性,重用性,靈活性等多方面的挑戰(zhàn),設(shè)計(jì)模式是為了讓程序(軟件)。具有更好
      1)代碼重用性(即:相同功能的代碼,不用多次編寫)
      2)可讀性(即:編程規(guī)范性,便于其他程序員的閱讀和理解)
      3)可擴(kuò)展性(即:當(dāng)需要增加新的功能時(shí),非常的方便,稱為可維護(hù))
      4)可靠性(即:當(dāng)我們?cè)黾有碌墓δ芎螅瑢?duì)原來的功能沒有影響)
      5)使程序呈現(xiàn)高內(nèi)聚,低耦合的特性
      6)設(shè)計(jì)模式包含了面向?qū)ο蟮木瑁岸嗽O(shè)計(jì)模式,你就懂了面向?qū)ο蠓治龊驮O(shè)計(jì)(OOA/D)的精要“
      7)Scott Mayers 在其巨著《Effective C++》就曾經(jīng)說過 :C++老手和C++新手的區(qū)別就是前者手背上有很多傷疤

      2 設(shè)計(jì)模式七大原則

      設(shè)計(jì)模式原則,其實(shí)就是程序員在編程時(shí),應(yīng)當(dāng)遵守的原則,也是各種設(shè)計(jì)模式的基礎(chǔ)(即:設(shè)計(jì)模式為什么這樣設(shè)計(jì)的依據(jù))
      設(shè)計(jì)模式常用的七大原則有 :
      1)單一職責(zé)原則
      2)接口隔離原則
      3)依賴倒轉(zhuǎn)(倒置)原則
      4)里氏替換原則
      5)開閉原則
      6)迪米特法則
      7)合成復(fù)用原則

      3 單一職責(zé)原則

      1 基本介紹

      對(duì)類來說的,即一個(gè)類應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)。如類A負(fù)責(zé)兩個(gè)不同職責(zé) :職責(zé)1,職責(zé)2。當(dāng)職責(zé)1需求變更而改變A時(shí),可能造成職責(zé)2執(zhí)行錯(cuò)誤,所以需要將類A的粒度分解為A1,A2

      2 應(yīng)用實(shí)例

      以交通工具案例講解

      package com.example.testdemo.mode.principle;
      
      public class SingleResponsibility1 {
      
          public static void main(String[] args) {
              Vehicle vehicle = new Vehicle();
              vehicle.run("摩托車");
              vehicle.run("汽車");
              vehicle.run("飛機(jī)");
          }
      
      }
      
      // 交通工具類
      
      /**
       * 方式1 :
       * 1 。 在方式1的run方法中,違反了單一職責(zé)原則
       * 2 。 解決的方案非常第二季簡(jiǎn)單,根據(jù)交通工具運(yùn)行方法不同,分解成不同類即可
       */
      class Vehicle {
      
          public void run(String vehicle) {
              System.out.println(vehicle + " 在公路上運(yùn)行。。。。。");
          }
      }
      package com.example.testdemo.mode.principle;
      
      public class SingleResponsibility2 {
      
          public static void main(String[] args) {
              ReadVehicle readVehicle = new ReadVehicle();
              readVehicle.run("摩托車");
              readVehicle.run("汽車");
              AirVehicle airVehicle = new AirVehicle();
              airVehicle.run("飛機(jī)");
              WaterVehicle waterVehicle = new WaterVehicle();
              waterVehicle.run("輪船");
          }
      
      }
      
      /**
       * 方案2分析 :
       * 1 :遵守單一職責(zé)原則
       * 2 :但是這樣改動(dòng)大,即將類分解,同時(shí)修改客戶端
       * 3 :改進(jìn) :直接修改Vehicle類,改動(dòng)的代碼會(huì)比較少 =》方案3
       *
       */
      class ReadVehicle {
          public void run(String vehicle) {
              System.out.println(vehicle + "公路運(yùn)行");
          }
      }
      
      class AirVehicle {
          public void run(String vehicle) {
              System.out.println(vehicle + "天空運(yùn)行");
          }
      }
      
      class WaterVehicle {
          public void run(String vehicle) {
              System.out.println(vehicle + "水中運(yùn)行");
          }
      }
      package com.example.testdemo.mode.principle;
      
      public class SingleResponsibility3 {
      
          public static void main(String[] args) {
              Vehicle2 vehicle2 = new Vehicle2();
              vehicle2.run("汽車");
              vehicle2.runAir("飛機(jī)");
              vehicle2.runWater("輪船");
          }
      
      }
      
      /**
       * 方案3的分析 :
       * 1 :這種修改方法沒有對(duì)原來的類做大的修改,只是增加方法
       * 2 :這里雖然沒有在類這個(gè)級(jí)別上遵守單一職責(zé)原則,但是在方法級(jí)別上,仍然是遵守單一職責(zé)
       */
      class Vehicle2 {
      
          public void run(String vehicle) {
              System.out.println(vehicle + " 在公路上運(yùn)行。。。。。");
          }
      
          public void runAir(String vehicle) {
              System.out.println(vehicle + " 在天空上運(yùn)行。。。。。");
          }
      
          public void runWater(String vehicle) {
              System.out.println(vehicle + " 在水中運(yùn)行。。。。。");
          }
      }

      單一職責(zé)原則注意事項(xiàng)和細(xì)節(jié)
      (1) 降低類的復(fù)雜度,一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé)。
      (2)提高類的可讀性,可維護(hù)性。
      (3)降低變更引起的風(fēng)險(xiǎn)。
      (4)通常情況下,我們應(yīng)當(dāng)遵守單一職責(zé)原則,只有邏輯足夠簡(jiǎn)單,才可以在代碼級(jí)違反單一職責(zé)原則 :只有類中方法數(shù)量足夠少,可以在方法級(jí)別保存單一職責(zé)原則。

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

      1 基本介紹

      (1)客戶端不應(yīng)該依賴它不需要的接口,即一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上

      (2)先看一張圖

      Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      (3)類A通過接口Interface1依賴類B,類C通過接口Interface1依賴類D,如果接口Interface1對(duì)于類A和類C來說不是最小接口,那么類B和類C必須去實(shí)現(xiàn)他們不需要的方法。

      (4)按隔離原則應(yīng)當(dāng)這樣處理 :

      將接口Interface1拆分為獨(dú)立的幾個(gè)接口這里我們拆分3個(gè)接口),類A和類C分別與他們需要的接口建立依賴關(guān)系,也就是采用接口隔離原則

      2 應(yīng)用實(shí)例

      1)類A通過接口Interface1依賴類B,類C通過接口Interface1依賴類D。
      2)沒有使用接口隔離原則的代碼

      package com.example.testdemo.mode.principle.segregation;
      
      import io.swagger.models.auth.In;
      
      public class Segregation1 {
      
          public static void main(String[] args) {
      
          }
      
      }
      
      /**
       * 接口
       */
      interface Interface1 {
          void operation1();
          void operation2();
          void operation3();
          void operation4();
          void operation5();
      }
      
      class B implements Interface1 {
      
          @Override
          public void operation1() {
              System.out.println(" B 實(shí)現(xiàn)了 operation1");
          }
      
          @Override
          public void operation2() {
              System.out.println(" B 實(shí)現(xiàn)了 operation2");
          }
      
          @Override
          public void operation3() {
              System.out.println(" B 實(shí)現(xiàn)了 operation3");
          }
      
          @Override
          public void operation4() {
              System.out.println(" B 實(shí)現(xiàn)了 operation4");
          }
      
          @Override
          public void operation5() {
              System.out.println(" B 實(shí)現(xiàn)了 operation5");
          }
      }
      
      class D implements Interface1 {
      
          @Override
          public void operation1() {
              System.out.println(" D 實(shí)現(xiàn)了 operation1");
          }
      
          @Override
          public void operation2() {
              System.out.println(" D 實(shí)現(xiàn)了 operation2");
          }
      
          @Override
          public void operation3() {
              System.out.println(" D 實(shí)現(xiàn)了 operation3");
          }
      
          @Override
          public void operation4() {
              System.out.println(" D 實(shí)現(xiàn)了 operation4");
          }
      
          @Override
          public void operation5() {
              System.out.println(" D 實(shí)現(xiàn)了 operation5");
          }
      }
      
      /**
       * A 類通過接口Interface1 依賴(使用)B類,但是只會(huì)用到1,2,3方法
       */
      class A {
          public void depend1(Interface1 interface1) {
              interface1.operation1();
          }
      
          public void depend2(Interface1 interface1) {
              interface1.operation2();
          }
      
          public void depend3(Interface1 interface1) {
              interface1.operation3();
          }
      }
      
      /**
       * C 類通過接口Interface1 依賴(使用)D類,但是只會(huì)用到1,4,5方法
       */
      class C {
          public void depend1(Interface1 interface1) {
              interface1.operation1();
          }
      
          public void depend4(Interface1 interface1) {
              interface1.operation4();
          }
      
          public void depend5(Interface1 interface1) {
              interface1.operation5();
          }
      }
      • 應(yīng)傳統(tǒng)方法的問題和接口隔離原則改進(jìn)
        (1)類A通過Interface1依賴類B,類C通過接口Interface1依賴類D,如果接口Interface1對(duì)于類A和類C來說不是最小接口,那么類B和類C必須去實(shí)現(xiàn)他們不需要的方法。
        (2)將接口Interface1拆分為獨(dú)立的幾個(gè)接口,類A和類C分別與他們需要的接口建立依賴關(guān)系。也就是采用接口隔離原則。
        (3)接口Interface1中出現(xiàn)的方法,根據(jù)實(shí)際情況拆分為三個(gè)接口
        (4)代碼實(shí)現(xiàn)

      • Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      package com.example.testdemo.mode.principle.segregation1;
      
      public class Segregation2 {
      
          public static void main(String[] args) {
              // 使用一把
              A a = new A();
              // A 類通過接口去依賴B類
              a.depend1(new B());
              a.depend2(new B());
              a.depend3(new B());
      
              // C 類通過接口去依賴(使用)D類
              C c = new C();
              c.depend1(new D());
              c.depend4(new D());
              c.depend5(new D());
          }
      }
      
      /**
       * 接口
       */
      interface Interface1 {
          void operation1();
      
      }
      
      interface Interface2 {
          void operation2();
      
          void operation3();
      }
      
      interface Interface3 {
      
          void operation4();
      
          void operation5();
      }
      
      class B implements Interface1, Interface2 {
      
          @Override
          public void operation1() {
              System.out.println(" B 實(shí)現(xiàn)了 operation1");
          }
      
          @Override
          public void operation2() {
              System.out.println(" B 實(shí)現(xiàn)了 operation2");
          }
      
          @Override
          public void operation3() {
              System.out.println(" B 實(shí)現(xiàn)了 operation3");
          }
      
      }
      
      class D implements Interface1, Interface3 {
      
          @Override
          public void operation1() {
              System.out.println(" D 實(shí)現(xiàn)了 operation1");
          }
      
          @Override
          public void operation4() {
              System.out.println(" D 實(shí)現(xiàn)了 operation4");
          }
      
          @Override
          public void operation5() {
              System.out.println(" D 實(shí)現(xiàn)了 operation5");
          }
      }
      
      /**
       * A 類通過接口Interface1 ,Interface2 依賴(使用)B類,但是只會(huì)用到1,2,3方法
       */
      class A {
          public void depend1(Interface1 interface1) {
              interface1.operation1();
          }
      
          public void depend2(Interface2 interface1) {
              interface1.operation2();
          }
      
          public void depend3(Interface2 interface1) {
              interface1.operation3();
          }
      }
      
      /**
       * C 類通過接口Interface1 ,Interface3 依賴(使用)D類,但是只會(huì)用到1,4,5方法
       */
      class C {
          public void depend1(Interface1 interface1) {
              interface1.operation1();
          }
      
          public void depend4(Interface3 interface1) {
              interface1.operation4();
          }
      
          public void depend5(Interface3 interface1) {
              interface1.operation5();
          }
      }

      5 依賴倒轉(zhuǎn)原則

      1 基本介紹

      依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)是指 :
      (1)高層模塊不應(yīng)該依賴底層模塊,二者都應(yīng)該依賴其抽象
      (2)抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴抽象
      (3)依賴倒轉(zhuǎn)(倒置)的中心思想是面向接口編程
      (4)依賴倒轉(zhuǎn)原則是基于這樣的設(shè)計(jì)理念 :相對(duì)于細(xì)節(jié)的多變性,抽象的東西要穩(wěn)定的多。以抽象為基礎(chǔ)搭建的架構(gòu)比以細(xì)節(jié)為基礎(chǔ)的架構(gòu)要穩(wěn)定的多。在java中,抽象指的是接口或抽象類,細(xì)節(jié)就是具體的實(shí)現(xiàn)類。
      (5)使用接口或抽象類的目的是制定好規(guī)范,而不涉及任何具體的操作,把展示細(xì)節(jié)的任務(wù)交給他們的實(shí)現(xiàn)類去完成。

      2 應(yīng)用實(shí)例

      1)方案1 + 分析說明

      package com.example.testdemo.mode.principle.inversion;
      
      public class DependecyInversion {
      
          public static void main(String[] args) {
              Person person = new Person();
              person.receive(new Email());
          }
      
      }
      
      class Email {
          public String getInfo() {
              return "電子郵件信息 :hello,world";
          }
      }
      
      /**
       * 完成Person接收消息的功能
       * 方式1分析
       * 1。簡(jiǎn)單,比較容易想到
       * 2。如果我們獲取的對(duì)象是微信,短信等等,則新增類,同時(shí)Persons也要增加相應(yīng)的接收方法
       * 3。解決思路 :引入一個(gè)抽象的接口IReceiver,表示接收者,這樣Person類與接口IReceiver發(fā)生依賴
       * 因?yàn)镋mail,微信等等屬于接收的范圍,他們各自實(shí)現(xiàn)IReceiver接口就ok,這樣我們就符合依賴倒轉(zhuǎn)原則
       */
      class Person {
          public void receive(Email email) {
              System.out.println(email.getInfo());
          }
      }

      2)方案2(依賴倒轉(zhuǎn))+ 分析說明

      package com.example.testdemo.mode.principle.inversion.inprove;
      
      public class DependecyInversion {
      
          public static void main(String[] args) {
              // 客戶端無需改變
              Person person = new Person();
              person.receive(new Email());
      
              person.receive(new WeiXin());
          }
      
      }
      
      /**
       * 定義接口
       */
      interface IReceiver {
          String getInfo();
      }
      
      class Email implements IReceiver{
      
          @Override
          public String getInfo() {
              return "電子郵件信息 :hello,world";
          }
      }
      
      /**
       * 增加微信
       */
      class WeiXin implements IReceiver {
      
          @Override
          public String getInfo() {
              return "微信消息 :hello ok";
          }
      }
      
      /**
       * 方式2
       */
      class Person {
          /**
           * 這里是我們對(duì)接口的依賴
           * @param iReceiver
           */
          public void receive(IReceiver iReceiver) {
              System.out.println(iReceiver.getInfo());
          }
      }

      依賴關(guān)系傳遞的三種方式 :
      1)接口傳遞
      2)構(gòu)造方法傳遞
      3)setter方法傳遞

      package com.example.testdemo.mode.principle.inversion.inprove;
      
      public class Dependecy {
          public static void main(String[] args) {
              IOpenAndClose iOpenAndClose = new OpenAndClose();
              iOpenAndClose.open(new ChangHong());
      
              IOpenAndClose2 iOpenAndClose2 = new OpenAndClose2(new XiaoMi());
              iOpenAndClose2.open();
      
              IOpenAndClose3 iOpenAndClose3 = new OpenAndClose3();
              iOpenAndClose3.setTv(new SanXing());
              iOpenAndClose3.open();
          }
      }
      
      /**
       * 方式1 :通過接口傳遞實(shí)現(xiàn)依賴
       */
      interface IOpenAndClose {
          /**
           * 抽象方法,接收接口
           * @param tv
           */
          void open(ITV tv);
      }
      
      /**
       * ITV接口
       */
      interface ITV {
          void play();
      }
      
      class ChangHong implements ITV {
      
          @Override
          public void play() {
              System.out.println("長(zhǎng)虹電視機(jī)打開");
          }
      }
      
      /**
       * 實(shí)現(xiàn)接口
       */
      class OpenAndClose implements IOpenAndClose {
      
          @Override
          public void open(ITV tv) {
              tv.play();
          }
      }
      
      /**
       * 方式2 :通過構(gòu)造方法依賴傳遞
       */
      interface IOpenAndClose2 {
          /**
           * 抽象方法
           */
          void open();
      }
      
      /**
       * ITV接口
       */
      interface ITV2 {
          void play();
      }
      
      class XiaoMi implements ITV2 {
      
          @Override
          public void play() {
              System.out.println("小米電視機(jī)打開");
          }
      }
      
      class OpenAndClose2 implements IOpenAndClose2 {
          /**
           * 成員屬性
           */
          public ITV2 tv;
      
          /**
           * 構(gòu)造方法
           * @param itv2
           */
          public OpenAndClose2(ITV2 itv2) {
              this.tv = itv2;
          }
      
          @Override
          public void open() {
              this.tv.play();
          }
      }
      
      /**
       * 方式3,通過setter方法傳遞
       */
      interface IOpenAndClose3 {
          /**
           * 抽象方法
           */
          void open();
      
          void setTv(ITV3 tv);
      }
      
      /**
       * ITV接口
       */
      interface ITV3 {
          void play();
      }
      
      class SanXing implements ITV3 {
      
          @Override
          public void play() {
              System.out.println("三星電視打開");
          }
      }
      
      class OpenAndClose3 implements IOpenAndClose3 {
      
          private ITV3 itv3;
      
          @Override
          public void open() {
              this.itv3.play();
          }
      
          @Override
          public void setTv(ITV3 tv) {
              this.itv3 = tv;
          }
      
      }

      依賴倒轉(zhuǎn)原則的注意事項(xiàng)和細(xì)節(jié)
      1)底層模塊盡力都要有抽象類或接口,或者兩者都有,程序穩(wěn)定性更好。
      2)變量的聲明類型盡量是抽象類或接口,這樣我們的變量引用和實(shí)際對(duì)象間,就存在一個(gè)緩存層,利于程序擴(kuò)展和優(yōu)化。
      3)繼承時(shí)遵循里氏替換原則。

      6 里氏替換原則

      1 OO中的繼承性的思考和說明

      1)繼承包含這樣一層含義 :父類中凡是已經(jīng)實(shí)現(xiàn)好的方法,實(shí)際上是在設(shè)定規(guī)范和契約,雖然它不強(qiáng)制要求所有的子類必須遵循這些契約,但是如果子類對(duì)象這些已經(jīng)實(shí)現(xiàn)的方法任意修改,就會(huì)對(duì)整個(gè)繼承體系造成破壞。
      2)繼承在給程序設(shè)計(jì)帶來便利的同時(shí),也帶來類弊端。比如使用繼承會(huì)給程序帶來侵入性,程序的可移植性降低,增加對(duì)象間的耦合性,如果一個(gè)類被其他的類所繼承,則當(dāng)這個(gè)類需要修改時(shí),必須考慮到所有的子類,并且父類修改后,所有涉及到子類的功能都有可能產(chǎn)生故障。
      3)問題提出 :在編程中,如何正確的使用繼承?=》里氏替換原則

      2 基本介紹

      1)里氏替換原則(Liskov Substitution Principle)在1988年,由麻省理工學(xué)院的一位姓里的女士提出的。
      2)如果對(duì)每個(gè)類型為T1的對(duì)象O1,都有類型為T2的對(duì)象O2,使得以T1定義的所有程序P在所有的對(duì)象O1都代換成O2時(shí),程序P的行為沒有變化,那么類型T2是類型T1的子類型。換句話說,所有引用基類的地方必須能透明地使用其子類的對(duì)象。
      3)在使用繼承時(shí),遵循里氏替換原則,在子類中盡量不要重寫父類的方法
      4)里氏替換原則告訴我們,繼承實(shí)際上讓兩個(gè)類耦合性增強(qiáng)了,在適當(dāng)?shù)那闆r下,可以通過聚合、組合、依賴來解決問題

      3 一個(gè)程序引出的問題和思考

      該看個(gè)程序,思考下問題和解決思路

      package com.example.testdemo.mode.principle.liskov;
      
      public class Liskov {
          public static void main(String[] args) {
              A a = new A();
              System.out.println("11 - 3 = " + a.funcl(11, 3));
              System.out.println("1 - 8  = " + a.funcl(1, 8));
      
              System.out.println("-----------------");
              B b = new B();
              // 這里本意是求出11 - 3
              System.out.println("11 - 3 = " + b.funcl(11, 3));
              // 1 - 8
              System.out.println("1 - 8  = " + b.funcl(1, 8));
              System.out.println("11 + 3 + 9 = " + b.func2(11, 3));
          }
      }
      
      class A {
          /**
           * 返回兩個(gè)數(shù)的差
           *
           * @param num1
           * @param num2
           * @return
           */
          public int funcl(int num1, int num2) {
              return num1 - num2;
          }
      }
      
      /**
       * B類繼承類A
       *
       * 增加類一個(gè)新功能 :完成兩個(gè)數(shù)相加,然后和9 求和
       */
      class B extends A {
      
          /**
           * 這里,重寫類A類的方法,可能是無意識(shí)
           * @param a
           * @param b
           * @return
           */
          @Override
          public int funcl(int a, int b) {
              return a + b;
          }
      
          public int func2(int a, int b) {
              return funcl(a, b) + 9;
          }
      
      }

      4 解決方法

      1)我們發(fā)現(xiàn)原來運(yùn)行正常的相減功能發(fā)生類錯(cuò)誤。原因就是類B無意中重寫父類的方法,造成原有功能出現(xiàn)錯(cuò)誤。在實(shí)際編程中,我們常常會(huì)通過重寫父類的方法完成新的功能,這樣寫起來雖然簡(jiǎn)單,但整個(gè)繼承體系的復(fù)用性會(huì)比較差。特別是運(yùn)行多態(tài)比較頻繁的時(shí)候。

      2)通用的做法是 :原來的父類和子類都繼承一個(gè)更通俗的基類,原有的繼承關(guān)系去掉,采用依賴、聚合、組合等關(guān)系代替。

      3)改進(jìn)方案。

      Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      package com.example.testdemo.mode.principle.improve;
      
      public class Liskov {
          public static void main(String[] args) {
              A a = new A();
              System.out.println("11 - 3 = " + a.func1(11, 3));
              System.out.println("1 - 8 = " + a.func1(1, 8));
      
              System.out.println("--------------------------");
              B b = new B();
              // 因?yàn)锽類不再繼承A類,因此調(diào)用者,不會(huì)再funcl是求減法
              // 調(diào)用完成的功能就會(huì)很明確
              // 這里本意是求出 11 + 3
              System.out.println("11 + 3 = " + b.func1(11, 3));
      
              // 1 + 8
              System.out.println("1 + 8 = " + b.func1(1, 8));
              System.out.println("11 + 3 + 9 = " + b.func2(11, 3));
      
              // 使用組合仍然可以使用到A類相關(guān)方法
              // 這里本意是求出 11 - 3
              System.out.println("11 - 3 = " + b.func3(11, 3));
          }
      }
      
      /**
       * 創(chuàng)建一個(gè)更加基礎(chǔ)的基類
       */
      class Base {
          // 把更加基礎(chǔ)的方法和成員寫B(tài)ase類
      }
      
      /**
       * A 類
       */
      class A extends Base {
      
          /**
           * 返回兩個(gè)數(shù)的差
           * @param num1
           * @param num2
           * @return
           */
          public int func1(int num1, int num2) {
              return num1 - num2;
          }
      }
      
      /**
       * B類 繼承了 A
       *
       * 增加類一個(gè)新功能 :完成兩個(gè)數(shù)相加,然后和9 求和
       */
      class B extends Base {
      
          /**
           * 如果B需要使用A類的方法,使用組合關(guān)系
           */
          private A a = new A();
      
          /**
           * 這里,重寫了A類方法,可能是無意識(shí)
           *
           * @param a
           * @param b
           * @return
           */
          public int func1(int a, int b) {
              return a + b;
          }
      
          public int func2(int a, int b) {
              return func1(a, b) + 9;
          }
      
          /**
           * 我們?nèi)匀幌胧褂肁的方法
           * @param a
           * @param b
           * @return
           */
          public int func3(int a, int b) {
              return this.a.func1(a,b);
          }
      
      }

      7 開閉原則

      1 基本介紹

      1)開閉原則(Open Closed Principle)是編程中最基礎(chǔ)、最重要的設(shè)計(jì)原則
      2)一個(gè)軟件實(shí)體如類,模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開放(對(duì)提供方),對(duì)修改關(guān)閉(對(duì)使用方)。用抽象構(gòu)建框架,用實(shí)現(xiàn)擴(kuò)展細(xì)節(jié)。
      3)當(dāng)軟件需要變化時(shí),盡量通過擴(kuò)展軟件實(shí)體的行為來實(shí)現(xiàn)變化,而不是通過修改已有的代碼來實(shí)現(xiàn)變化。
      4)編程中遵循其它原則,以及使用設(shè)計(jì)模式的目的就是遵循開閉原則。

      2 看下面一段代碼

      看一個(gè)畫圖形的功能。

      類圖設(shè)計(jì),如下 :

      Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      package com.example.demo.ocp;
      
      public class Ocp {
      
          public static void main(String[] args) {
               // 使用可靠存在的問題
              GraphicEditor graphicEditor = new GraphicEditor();
              graphicEditor.drawShape(new Rectangle());
              graphicEditor.drawShape(new Circle());
              graphicEditor.drawShape(new Triangle());
          }
      
      }
      
      /**
       * 這是一個(gè)用于繪圖的類(使用方)
       */
      class GraphicEditor {
      
          /**
           * 接收Shape對(duì)象,然后根據(jù)type,來繪制不同的圖形
           * @param shape
           */
          public void drawShape(Shape shape) {
              if (shape.m_type == 1) {
                  drawRectangle(shape);
              } else if (shape.m_type == 2) {
                  drawCircle(shape);
              } else if (shape.m_type == 3) {
                  drawTriangle(shape);
              }
          }
      
          /**
           * 繪制三角形
           * @param shape
           */
          private void drawTriangle(Shape shape) {
              System.out.println("繪制三角形");
          }
      
          /**
           * 繪制圓形
           * @param shape
           */
          private void drawCircle(Shape shape) {
              System.out.println("繪制圓形");
          }
      
      
          /**
           * 繪制矩形
           * @param shape
           */
          private void drawRectangle(Shape shape) {
              System.out.println("繪制矩形");
          }
      
      }
      
      /**
       * Shape類,基類
       */
      class Shape {
          int m_type;
      }
      
      class Rectangle extends Shape {
          Rectangle() {
              super.m_type = 1;
          }
      }
      
      class Circle extends Shape {
      
          Circle() {
              super.m_type = 2;
          }
      }
      
      /**
       * 新增畫三角形
       */
      class Triangle extends Shape {
          Triangle() {
              super.m_type = 3;
          }
      }

      3 方式1的優(yōu)缺點(diǎn)

      1)優(yōu)點(diǎn)是比較好理解,簡(jiǎn)單易操作。
      2)缺點(diǎn)是違反了設(shè)計(jì)模式的ocp原則,即對(duì)擴(kuò)展開放(提供方),對(duì)修改關(guān)閉(使用方)。即當(dāng)我們給類增加新功能的時(shí)候,盡量不修改代碼,或者盡可能少修改代碼。
      3)比如我們這時(shí)要新增加一個(gè)圖形種類 三角形,我們需要做很多修改,修改的地方比較多。

      4 改進(jìn)的思路分析

      思路 : 把創(chuàng)建Shape類做成抽象類,并提供一個(gè)抽象的draw方法,讓子類去實(shí)現(xiàn)即可,這樣我們有新的圖形種類時(shí),只需要讓新的圖形類繼承Shape,并實(shí)現(xiàn)draw方法即可,使用方的代碼就不需要修改 -》
      滿足了開閉原則
      改進(jìn)后的代碼 :

      package com.example.demo.ocp.improve;
      
      public class Ocp {
          public static void main(String[] args) {
              // 使用看看存在的問題
              GraphicEditor graphicEditor = new GraphicEditor();
              graphicEditor.drawShape(new Rectangle());
              graphicEditor.drawShape(new Circle());
              graphicEditor.drawShape(new Triangle());
              graphicEditor.drawShape(new OtherGraphic());
          }
      }
      
      /**
       * 這是一個(gè)用于繪圖的類(使用方)
       */
      class GraphicEditor {
      
          /**
           * 接收Shape對(duì)象,調(diào)用draw方法
           * @param shape
           */
          public void drawShape(Shape shape) {
              shape.draw();
          }
      }
      
      /**
       * Shape類,基類
       */
      abstract class Shape {
          int m_type;
      
          /**
           * 抽象方法
           */
          public abstract void draw();
      }
      
      class Rectangle extends Shape {
      
          Rectangle() {
              super.m_type = 1;
          }
      
          @Override
          public void draw() {
              System.out.println("繪制矩形");
          }
      }
      
      class Circle extends Shape {
      
          Circle() {
              super.m_type = 2;
          }
      
          @Override
          public void draw() {
              System.out.println("繪制圓形");
          }
      }
      
      /**
       * 新增畫三角形
       */
      class Triangle extends Shape {
      
          Triangle() {
              super.m_type = 3;
          }
      
          @Override
          public void draw() {
              System.out.println("繪制三角形");
          }
      }
      
      /**
       * 新增一個(gè)圖形
       */
      class OtherGraphic extends Shape {
      
          OtherGraphic() {
              super.m_type = 4;
          }
      
          @Override
          public void draw() {
              System.out.println("繪制其他圖形");
          }
      }

      8 迪米特法則

      1 基本介紹

      1)一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象保持最少的了解。
      2)類與類關(guān)系越密切,耦合度越大。
      3)迪米特法則(Demeter Principle)又叫最少知道原則,即一個(gè)類對(duì)自己依賴的類知道的越少越好。也就是說,對(duì)于被依賴的類不管多么復(fù)雜,都盡量將邏輯封裝在類的內(nèi)部。對(duì)外除了提供的public方法,不對(duì)外泄露任何信息。
      4)迪米特法則還有個(gè)簡(jiǎn)單的定義 :只與直接的朋友通信。
      5)直接的朋友 :每個(gè)對(duì)象都會(huì)與其他對(duì)象有耦合關(guān)系,只要兩個(gè)對(duì)象之間有耦合關(guān)系,我們就說這兩個(gè)對(duì)象之間是朋友關(guān)系。耦合的方式很多,依賴、關(guān)聯(lián)組合、聚合等。其中,我們稱出現(xiàn)成員變量,方法參數(shù),方法返回值中的類為直接的朋友,而出現(xiàn)在局部變量中的類不是直接的朋友。也就是說,陌生的類最好不要以局部變量的形式出現(xiàn)在類的內(nèi)部。

      2 應(yīng)用實(shí)例

      1)有一個(gè)學(xué)校,下屬有各個(gè)學(xué)院和總部,現(xiàn)要求打印出學(xué)校總部員工ID和學(xué)院?jiǎn)T工的id
      2)編程實(shí)現(xiàn)上面的功能,看代碼演示
      3)代碼演示

      package com.example.demo.demeter;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * 客戶端
       */
      public class Demeter1 {
      
          public static void main(String[] args) {
              // 創(chuàng)建一個(gè) SchoolManager 對(duì)象
              SchoolManager schoolManager = new SchoolManager();
              // 輸出學(xué)院的員工id 和 學(xué)院總部的員工信息
              schoolManager.printAllEmployee(new CollegeManager());
          }
      
      }
      
      /**
       * 學(xué)校總部員工類
       */
      class Employee {
      
          private String id;
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      }
      
      /**
       * 學(xué)院的員工類
       */
      class CollegeEmployee {
      
          private String id;
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      }
      
      /**
       * 管理學(xué)院?jiǎn)T工的管理類
       */
      class CollegeManager {
      
          /**
           * 返回學(xué)院的所有員工
           * @return
           */
          public List getAllEmployee() {
              List employees = new ArrayList<>();
              // 這里我們?cè)黾恿?0個(gè)員工到list
              for (int i = 0; i < 10; i++) {
                  CollegeEmployee collegeEmployee = new CollegeEmployee();
                  collegeEmployee.setId("學(xué)院?jiǎn)T工 id = " + i);
                  employees.add(collegeEmployee);
              }
              return employees;
          }
      }
      
      /**
       * 學(xué)校管理類
       *
       * 分析 SchoolManager 類的直接朋友類有哪些 Employee、CollegeManager
       * CollegeEmployee 不是 直接朋友,而是一個(gè)陌生類,這樣違背了迪米特法則
       *
       */
      class SchoolManager {
      
          /**
           * 返回學(xué)校總部的員工
           * @return
           */
          public List getAllEmployee() {
              List list = new ArrayList<>();
              // 這里我們?cè)黾恿?個(gè)員工到list
              for (int i = 0; i < 5; i++) {
                  Employee employee = new Employee();
                  employee.setId("學(xué)校總部員工 id = " + i);
                  list.add(employee);
              }
              return list;
          }
      
          /**
           * 該方法完成輸出學(xué)校總部和學(xué)院?jiǎn)T工信息 (id)
           * @param collegeManager
           */
          void printAllEmployee(CollegeManager collegeManager) {
              // 分析問題
              // 1. 這里的 CollegeEmployee 不是 SchoolManageer的直接朋友
              // 2. CollegeEmployee 是以局部變量方式出現(xiàn)在 SchoolManager
              // 3. 違反了 迪米特法則
              // 獲取到學(xué)院?jiǎn)T工
              List allEmployee = collegeManager.getAllEmployee();
              System.out.println("-------------學(xué)院?jiǎn)T工-------------");
              for (CollegeEmployee collegeEmployee : allEmployee) {
                  System.out.println(collegeEmployee.getId());
              }
              // 獲取到學(xué)院總部員工
              List employee = this.getAllEmployee();
              System.out.println("-----------學(xué)校總部員工-------------");
              for (Employee employee1 : employee) {
                  System.out.println(employee1.getId());
              }
          }
      }

      3 應(yīng)用實(shí)例改進(jìn)

      1)前面設(shè)計(jì)的問題在于SchoolManager中,CollegeEmployee類并不是SchoolManager類的直接朋友(分析)
      2)按照迪米特法則,應(yīng)該避免類中出現(xiàn)這樣非直接朋友關(guān)系的耦合
      3)對(duì)代碼按照迪米特法則進(jìn)行改進(jìn)。
      4)代碼演示

      package com.example.demo.demeter.improve;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * 客戶端
       */
      public class Demeter1 {
      
          public static void main(String[] args) {
              // 創(chuàng)建一個(gè) SchoolManager 對(duì)象
              SchoolManager schoolManager = new SchoolManager();
              // 輸出學(xué)院的員工id 和 學(xué)院總部的員工信息
              schoolManager.printAllEmployee(new CollegeManager());
          }
      
      }
      
      /**
       * 學(xué)校總部員工類
       */
      class Employee {
      
          private String id;
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      }
      
      /**
       * 學(xué)院的員工類
       */
      class CollegeEmployee {
      
          private String id;
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      }
      
      /**
       * 管理學(xué)院?jiǎn)T工的管理類
       */
      class CollegeManager {
      
          /**
           * 返回學(xué)院的所有員工
           * @return
           */
          public List getAllEmployee() {
              List employees = new ArrayList<>();
              // 這里我們?cè)黾恿?0個(gè)員工到list
              for (int i = 0; i < 10; i++) {
                  CollegeEmployee collegeEmployee = new CollegeEmployee();
                  collegeEmployee.setId("學(xué)院?jiǎn)T工 id = " + i);
                  employees.add(collegeEmployee);
              }
              return employees;
          }
      
          /**
           * 輸出學(xué)院?jiǎn)T工的信息
           */
          public void printEmployee() {
              // 獲取到學(xué)院?jiǎn)T工
              List allEmployee = getAllEmployee();
              System.out.println("----------學(xué)院?jiǎn)T工-----------");
              for (CollegeEmployee collegeEmployee : allEmployee) {
                  System.out.println(collegeEmployee.getId());
              }
          }
      }
      
      /**
       * 學(xué)校管理類
       *
       * 分析 SchoolManager 類的直接朋友類有哪些 Employee、CollegeManager
       * CollegeEmployee 不是 直接朋友,而是一個(gè)陌生類,這樣違背了迪米特法則
       *
       */
      class SchoolManager {
      
          /**
           * 返回學(xué)校總部的員工
           * @return
           */
          public List getAllEmployee() {
              List list = new ArrayList<>();
              // 這里我們?cè)黾恿?個(gè)員工到list
              for (int i = 0; i < 5; i++) {
                  Employee employee = new Employee();
                  employee.setId("學(xué)校總部員工 id = " + i);
                  list.add(employee);
              }
              return list;
          }
      
          /**
           * 該方法完成輸出學(xué)校總部和學(xué)院?jiǎn)T工信息 (id)
           * @param collegeManager
           */
          void printAllEmployee(CollegeManager collegeManager) {
              // 分析問題
              // 1. 將輸出學(xué)院的員工方法,封裝到CollegeManager
              collegeManager.printEmployee();
              // 獲取到學(xué)院總部員工
              List employee = this.getAllEmployee();
              System.out.println("-----------學(xué)校總部員工-------------");
              for (Employee employee1 : employee) {
                  System.out.println(employee1.getId());
              }
          }
      }

      4 迪米特法則注意事項(xiàng)和細(xì)節(jié)

      1)迪米特法則的核心是降低類之間的耦合
      2)但是注意 :由于每個(gè)類都減少了不必要的依賴,因此迪米特法則只是要求降低類間(對(duì)象間)耦合關(guān)系,并不是要求完全沒有依賴關(guān)系。

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

      基本介紹 :原則是盡量使用合成/聚合的方式,而不是使用繼承。

      Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)

      設(shè)計(jì)原則核心思想

      1)找出應(yīng)用中可能需要變換之處,把它們獨(dú)立出來,不要和那些需要變化的代碼混在一起。
      2)針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程。
      3)為了交互對(duì)象之間的松耦合設(shè)計(jì)而努力。

      讀到這里,這篇“Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


      本文標(biāo)題:Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)
      文章分享:http://www.ef60e0e.cn/article/gppsoo.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        德兴市| 永安市| 天台县| 改则县| 华安县| 南宁市| 乌鲁木齐市| 揭西县| 丹凤县| 西乌珠穆沁旗| 大宁县| 清徐县| 沭阳县| 遵义县| 丰原市| 阿克陶县| 德安县| 大田县| 浪卡子县| 龙川县| 韩城市| 浙江省| 江华| 涞水县| 全南县| 海门市| 六盘水市| 碌曲县| 北碚区| 吴川市| 施甸县| 土默特左旗| 绥中县| 连平县| 元氏县| 双峰县| 左云县| 武川县| 梓潼县| 宣恩县| 长沙市|