欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

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)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

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

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

編寫(xiě)軟件過(guò)程中,程序員面臨著來(lái)自耦合性,內(nèi)聚性以及可維護(hù)性,可擴(kuò)展性,重用性,靈活性等多方面的挑戰(zhàn),設(shè)計(jì)模式是為了讓程序(軟件)。具有更好
1)代碼重用性(即:相同功能的代碼,不用多次編寫(xiě))
2)可讀性(即:編程規(guī)范性,便于其他程序員的閱讀和理解)
3)可擴(kuò)展性(即:當(dāng)需要增加新的功能時(shí),非常的方便,稱(chēng)為可維護(hù))
4)可靠性(即:當(dāng)我們?cè)黾有碌墓δ芎?,?duì)原來(lái)的功能沒(méi)有影響)
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)說(shuō)過(guò) :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)依賴(lài)倒轉(zhuǎn)(倒置)原則
4)里氏替換原則
5)開(kāi)閉原則
6)迪米特法則
7)合成復(fù)用原則

3 單一職責(zé)原則

1 基本介紹

對(duì)類(lèi)來(lái)說(shuō)的,即一個(gè)類(lèi)應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)。如類(lèi)A負(fù)責(zé)兩個(gè)不同職責(zé) :職責(zé)1,職責(zé)2。當(dāng)職責(zé)1需求變更而改變A時(shí),可能造成職責(zé)2執(zhí)行錯(cuò)誤,所以需要將類(lèi)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("摩托車(chē)");
        vehicle.run("汽車(chē)");
        vehicle.run("飛機(jī)");
    }

}

// 交通工具類(lèi)

/**
 * 方式1 :
 * 1 。 在方式1的run方法中,違反了單一職責(zé)原則
 * 2 。 解決的方案非常第二季簡(jiǎn)單,根據(jù)交通工具運(yùn)行方法不同,分解成不同類(lèi)即可
 */
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("摩托車(chē)");
        readVehicle.run("汽車(chē)");
        AirVehicle airVehicle = new AirVehicle();
        airVehicle.run("飛機(jī)");
        WaterVehicle waterVehicle = new WaterVehicle();
        waterVehicle.run("輪船");
    }

}

/**
 * 方案2分析 :
 * 1 :遵守單一職責(zé)原則
 * 2 :但是這樣改動(dòng)大,即將類(lèi)分解,同時(shí)修改客戶(hù)端
 * 3 :改進(jìn) :直接修改Vehicle類(lèi),改動(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("汽車(chē)");
        vehicle2.runAir("飛機(jī)");
        vehicle2.runWater("輪船");
    }

}

/**
 * 方案3的分析 :
 * 1 :這種修改方法沒(méi)有對(duì)原來(lái)的類(lèi)做大的修改,只是增加方法
 * 2 :這里雖然沒(méi)有在類(lèi)這個(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) 降低類(lèi)的復(fù)雜度,一個(gè)類(lèi)只負(fù)責(zé)一項(xiàng)職責(zé)。
(2)提高類(lèi)的可讀性,可維護(hù)性。
(3)降低變更引起的風(fēng)險(xiǎn)。
(4)通常情況下,我們應(yīng)當(dāng)遵守單一職責(zé)原則,只有邏輯足夠簡(jiǎn)單,才可以在代碼級(jí)違反單一職責(zé)原則 :只有類(lèi)中方法數(shù)量足夠少,可以在方法級(jí)別保存單一職責(zé)原則。

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

1 基本介紹

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

(2)先看一張圖

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

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

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

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

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

1)類(lèi)A通過(guò)接口Interface1依賴(lài)類(lèi)B,類(lèi)C通過(guò)接口Interface1依賴(lài)類(lèi)D。
2)沒(méi)有使用接口隔離原則的代碼

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 類(lèi)通過(guò)接口Interface1 依賴(lài)(使用)B類(lèi),但是只會(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 類(lèi)通過(guò)接口Interface1 依賴(lài)(使用)D類(lèi),但是只會(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)方法的問(wèn)題和接口隔離原則改進(jìn)
    (1)類(lèi)A通過(guò)Interface1依賴(lài)類(lèi)B,類(lèi)C通過(guò)接口Interface1依賴(lài)類(lèi)D,如果接口Interface1對(duì)于類(lèi)A和類(lèi)C來(lái)說(shuō)不是最小接口,那么類(lèi)B和類(lèi)C必須去實(shí)現(xiàn)他們不需要的方法。
    (2)將接口Interface1拆分為獨(dú)立的幾個(gè)接口,類(lèi)A和類(lèi)C分別與他們需要的接口建立依賴(lài)關(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 類(lèi)通過(guò)接口去依賴(lài)B類(lèi)
        a.depend1(new B());
        a.depend2(new B());
        a.depend3(new B());

        // C 類(lèi)通過(guò)接口去依賴(lài)(使用)D類(lèi)
        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 類(lèi)通過(guò)接口Interface1 ,Interface2 依賴(lài)(使用)B類(lèi),但是只會(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 類(lèi)通過(guò)接口Interface1 ,Interface3 依賴(lài)(使用)D類(lèi),但是只會(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 依賴(lài)倒轉(zhuǎn)原則

1 基本介紹

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

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

1)方案1 + 分析說(shuō)明

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ì)象是微信,短信等等,則新增類(lèi),同時(shí)Persons也要增加相應(yīng)的接收方法
 * 3。解決思路 :引入一個(gè)抽象的接口IReceiver,表示接收者,這樣Person類(lèi)與接口IReceiver發(fā)生依賴(lài)
 * 因?yàn)镋mail,微信等等屬于接收的范圍,他們各自實(shí)現(xiàn)IReceiver接口就ok,這樣我們就符合依賴(lài)倒轉(zhuǎn)原則
 */
class Person {
    public void receive(Email email) {
        System.out.println(email.getInfo());
    }
}

2)方案2(依賴(lài)倒轉(zhuǎn))+ 分析說(shuō)明

package com.example.testdemo.mode.principle.inversion.inprove;

public class DependecyInversion {

    public static void main(String[] args) {
        // 客戶(hù)端無(wú)需改變
        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ì)接口的依賴(lài)
     * @param iReceiver
     */
    public void receive(IReceiver iReceiver) {
        System.out.println(iReceiver.getInfo());
    }
}

依賴(lài)關(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 :通過(guò)接口傳遞實(shí)現(xiàn)依賴(lài)
 */
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ī)打開(kāi)");
    }
}

/**
 * 實(shí)現(xiàn)接口
 */
class OpenAndClose implements IOpenAndClose {

    @Override
    public void open(ITV tv) {
        tv.play();
    }
}

/**
 * 方式2 :通過(guò)構(gòu)造方法依賴(lài)傳遞
 */
interface IOpenAndClose2 {
    /**
     * 抽象方法
     */
    void open();
}

/**
 * ITV接口
 */
interface ITV2 {
    void play();
}

class XiaoMi implements ITV2 {

    @Override
    public void play() {
        System.out.println("小米電視機(jī)打開(kāi)");
    }
}

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,通過(guò)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("三星電視打開(kāi)");
    }
}

class OpenAndClose3 implements IOpenAndClose3 {

    private ITV3 itv3;

    @Override
    public void open() {
        this.itv3.play();
    }

    @Override
    public void setTv(ITV3 tv) {
        this.itv3 = tv;
    }

}

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

6 里氏替換原則

1 OO中的繼承性的思考和說(shuō)明

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

2 基本介紹

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

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

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

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類(lèi)繼承類(lèi)A
 *
 * 增加類(lèi)一個(gè)新功能 :完成兩個(gè)數(shù)相加,然后和9 求和
 */
class B extends A {

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

2)通用的做法是 :原來(lái)的父類(lèi)和子類(lèi)都繼承一個(gè)更通俗的基類(lèi),原有的繼承關(guān)系去掉,采用依賴(lài)、聚合、組合等關(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)锽類(lèi)不再繼承A類(lèi),因此調(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類(lèi)相關(guān)方法
        // 這里本意是求出 11 - 3
        System.out.println("11 - 3 = " + b.func3(11, 3));
    }
}

/**
 * 創(chuàng)建一個(gè)更加基礎(chǔ)的基類(lèi)
 */
class Base {
    // 把更加基礎(chǔ)的方法和成員寫(xiě)B(tài)ase類(lèi)
}

/**
 * A 類(lèi)
 */
class A extends Base {

    /**
     * 返回兩個(gè)數(shù)的差
     * @param num1
     * @param num2
     * @return
     */
    public int func1(int num1, int num2) {
        return num1 - num2;
    }
}

/**
 * B類(lèi) 繼承了 A
 *
 * 增加類(lèi)一個(gè)新功能 :完成兩個(gè)數(shù)相加,然后和9 求和
 */
class B extends Base {

    /**
     * 如果B需要使用A類(lèi)的方法,使用組合關(guān)系
     */
    private A a = new A();

    /**
     * 這里,重寫(xiě)了A類(lèi)方法,可能是無(wú)意識(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 開(kāi)閉原則

1 基本介紹

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

2 看下面一段代碼

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

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

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

package com.example.demo.ocp;

public class Ocp {

    public static void main(String[] args) {
         // 使用可靠存在的問(wèn)題
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
    }

}

/**
 * 這是一個(gè)用于繪圖的類(lèi)(使用方)
 */
class GraphicEditor {

    /**
     * 接收Shape對(duì)象,然后根據(jù)type,來(lái)繪制不同的圖形
     * @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類(lèi),基類(lèi)
 */
class Shape {
    int m_type;
}

class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }
}

class Circle extends Shape {

    Circle() {
        super.m_type = 2;
    }
}

/**
 * 新增畫(huà)三角形
 */
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ò)展開(kāi)放(提供方),對(duì)修改關(guān)閉(使用方)。即當(dāng)我們給類(lèi)增加新功能的時(shí)候,盡量不修改代碼,或者盡可能少修改代碼。
3)比如我們這時(shí)要新增加一個(gè)圖形種類(lèi) 三角形,我們需要做很多修改,修改的地方比較多。

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

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

package com.example.demo.ocp.improve;

public class Ocp {
    public static void main(String[] args) {
        // 使用看看存在的問(wèn)題
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
        graphicEditor.drawShape(new OtherGraphic());
    }
}

/**
 * 這是一個(gè)用于繪圖的類(lèi)(使用方)
 */
class GraphicEditor {

    /**
     * 接收Shape對(duì)象,調(diào)用draw方法
     * @param shape
     */
    public void drawShape(Shape shape) {
        shape.draw();
    }
}

/**
 * Shape類(lèi),基類(lèi)
 */
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("繪制圓形");
    }
}

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

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

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

package com.example.demo.demeter;

import java.util.ArrayList;
import java.util.List;

/**
 * 客戶(hù)端
 */
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é)??偛繂T工類(lèi)
 */
class Employee {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

/**
 * 學(xué)院的員工類(lèi)
 */
class CollegeEmployee {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

/**
 * 管理學(xué)院?jiǎn)T工的管理類(lèi)
 */
class CollegeManager {

    /**
     * 返回學(xué)院的所有員工
     * @return
     */
    public List<CollegeEmployee> getAllEmployee() {
        List<CollegeEmployee> 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é)校管理類(lèi)
 *
 * 分析 SchoolManager 類(lèi)的直接朋友類(lèi)有哪些 Employee、CollegeManager
 * CollegeEmployee 不是 直接朋友,而是一個(gè)陌生類(lèi),這樣違背了迪米特法則
 *
 */
class SchoolManager {

    /**
     * 返回學(xué)校總部的員工
     * @return
     */
    public List<Employee> getAllEmployee() {
        List<Employee> list = new ArrayList<>();
        // 這里我們?cè)黾恿?個(gè)員工到list
        for (int i = 0; i < 5; i++) {
            Employee employee = new Employee();
            employee.setId("學(xué)??偛繂T工 id = " + i);
            list.add(employee);
        }
        return list;
    }

    /**
     * 該方法完成輸出學(xué)??偛亢蛯W(xué)院?jiǎn)T工信息 (id)
     * @param collegeManager
     */
    void printAllEmployee(CollegeManager collegeManager) {
        // 分析問(wèn)題
        // 1. 這里的 CollegeEmployee 不是 SchoolManageer的直接朋友
        // 2. CollegeEmployee 是以局部變量方式出現(xiàn)在 SchoolManager
        // 3. 違反了 迪米特法則
        // 獲取到學(xué)院?jiǎn)T工
        List<CollegeEmployee> allEmployee = collegeManager.getAllEmployee();
        System.out.println("-------------學(xué)院?jiǎn)T工-------------");
        for (CollegeEmployee collegeEmployee : allEmployee) {
            System.out.println(collegeEmployee.getId());
        }
        // 獲取到學(xué)院總部員工
        List<Employee> employee = this.getAllEmployee();
        System.out.println("-----------學(xué)??偛繂T工-------------");
        for (Employee employee1 : employee) {
            System.out.println(employee1.getId());
        }
    }
}

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

1)前面設(shè)計(jì)的問(wèn)題在于SchoolManager中,CollegeEmployee類(lèi)并不是SchoolManager類(lèi)的直接朋友(分析)
2)按照迪米特法則,應(yīng)該避免類(lèi)中出現(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;

/**
 * 客戶(hù)端
 */
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é)校總部員工類(lèi)
 */
class Employee {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

/**
 * 學(xué)院的員工類(lèi)
 */
class CollegeEmployee {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

/**
 * 管理學(xué)院?jiǎn)T工的管理類(lèi)
 */
class CollegeManager {

    /**
     * 返回學(xué)院的所有員工
     * @return
     */
    public List<CollegeEmployee> getAllEmployee() {
        List<CollegeEmployee> 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<CollegeEmployee> allEmployee = getAllEmployee();
        System.out.println("----------學(xué)院?jiǎn)T工-----------");
        for (CollegeEmployee collegeEmployee : allEmployee) {
            System.out.println(collegeEmployee.getId());
        }
    }
}

/**
 * 學(xué)校管理類(lèi)
 *
 * 分析 SchoolManager 類(lèi)的直接朋友類(lèi)有哪些 Employee、CollegeManager
 * CollegeEmployee 不是 直接朋友,而是一個(gè)陌生類(lèi),這樣違背了迪米特法則
 *
 */
class SchoolManager {

    /**
     * 返回學(xué)??偛康膯T工
     * @return
     */
    public List<Employee> getAllEmployee() {
        List<Employee> 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é)??偛亢蛯W(xué)院?jiǎn)T工信息 (id)
     * @param collegeManager
     */
    void printAllEmployee(CollegeManager collegeManager) {
        // 分析問(wèn)題
        // 1. 將輸出學(xué)院的員工方法,封裝到CollegeManager
        collegeManager.printEmployee();
        // 獲取到學(xué)院總部員工
        List<Employee> employee = this.getAllEmployee();
        System.out.println("-----------學(xué)??偛繂T工-------------");
        for (Employee employee1 : employee) {
            System.out.println(employee1.getId());
        }
    }
}

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

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

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

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

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

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

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

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

網(wǎng)頁(yè)標(biāo)題:Java設(shè)計(jì)模式七大原則是什么及怎么實(shí)現(xiàn)
文章起源:http://aaarwkj.com/article0/gppsoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航小程序開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站設(shè)計(jì)標(biāo)簽優(yōu)化、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
日韩中文字幕一区二区不卡| 日韩精品毛片一区到三区| 亚洲巨人精品福利导航| 91成人大片在线观看| 香蕉视频欧美久久精品| 欧美视频免费一级黄片| 免费国产污在线观看网站| 性生活自制视频网站麻豆| 加勒比中文字幕日本道| 日本中文有码在线观看| 免费午夜福利一区二区| 色哟哟网站一区二区精品久久| 高清不卡av在线播放| 97乱碰视频在线观看| 亚洲av永久精品桃色| 亚洲欧美国产另类精品| 另类视频在线观看免费| 美女高潮呻吟免费观看久久久| 一个人看的视频天堂色| 日韩无码一区二区视频| 国产成人av三级在线观看| 亚洲乱码一区二区免费版| 久久综合视频大片视频| 国产精品三级av在线播放| 黄色片一区二区三区四区| 风韵丰满熟妇啪啪老熟女| 国产一区 亚洲精品| 欧美亚洲五月婷婷激情| 亚洲精品伦理中文字幕| 91出品国产福利在线| 精品少妇人妻一区二区三区| 日本在线观看精品综合| 久久久久亚洲av成人| 婷婷六月亚洲中文字幕| 亚洲一区二区美女av| 91天美精东果冻麻豆| 亚洲久久精品一区二区| 午夜视频在线观看91| 国产欧美日韩综合91| 观看女性真实高潮的合集| 亚洲美女毛茸茸的逼逼|