第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

接口如何打破類的依賴關(guān)系?

接口如何打破類的依賴關(guān)系?

幕布斯7119047 2022-09-14 10:37:37
我正在閱讀鮑勃·馬丁的《清潔建筑》。他談到了用接口打破依賴關(guān)系。例如。B 類使用 A 類。因此,B 類依賴于類 A(B → A)。我們可以添加一個接口,讓 B 依賴于接口,也讓 A 依賴于接口(A → I ← B)。我不明白的是,如果類A具有在B需要的函數(shù)中使用的私有成員變量,那么我是否不必重寫B(tài)中與A相同的代碼?另外,這不就是重復(fù)的代碼嗎?下面是一個示例。class Car {    private String color;    private Integer numberOfTires;    [...]    public void printCar()    {        System.out.print("Color: " + color);        System.out.print("Number of tires: " + numberOfTires);    }}class Inventory{    private Car car;    private Truck truck; // Left out for brevity    public void printCar()    {        car.printCar();    }    public void printTruck()    {        truck.printTruck();    }}我不明白接口如何幫助解決這種依賴關(guān)系。
查看完整描述

4 回答

?
素胚勾勒不出你

TA貢獻(xiàn)1827條經(jīng)驗 獲得超9個贊

考?!の鳡柧S拉提供了一個很好的例子,但沒有提到另一個重要方面。

通常,接口的要點不是要有更少的類。我想你熟悉耦合內(nèi)聚這兩個術(shù)語。您總是希望擁有松散耦合且高度內(nèi)聚的代碼。

這意味著,您不希望類相互依賴(耦合),而是以繼承,多態(tài)性等形式共享一些邏輯。這些概念是質(zhì)量對象導(dǎo)向設(shè)計的一些基本支柱。如果您不熟悉這些主題,絕對值得一讀。

回到這個問題,如果你正在處理一個有很多特殊情況的復(fù)雜邏輯,你通常會有一些重復(fù)。但是,這些問題與其他設(shè)計模式和原則更相關(guān),這些模式和原則僅用于遵守 DRY 原則,并以推廣解決方案方法的方式解決情況。

接口背后的主要思想是為類設(shè)置一個邏輯結(jié)構(gòu),這有助于對象操作的統(tǒng)一性。

想象一個證券交易所系統(tǒng)。

此接口具有一個名為 execute 的方法,該方法將執(zhí)行一些應(yīng)用程序邏輯。

public interface Order{     void execute();
}

可能實現(xiàn)此接口的其他類可能是買入賣出。它看起來像這樣:

public class Buy implement Order{     @Override
     public void execute(){          //TODO: Some logic
     }
}

現(xiàn)在,買入賣出都有類似的代碼,甚至可能有一些重復(fù)的代碼,但更重要的是,當(dāng)它們實現(xiàn)相同的接口時,你可以以統(tǒng)一的方式處理它們。您可以有一些股票管理器類,該類會在某些 . 由此可以得出結(jié)論,在使用此類隊列時,您將能夠在 Order 接口的任何實現(xiàn)上調(diào)用該方法。Queue<Order>execute()

在前面的論點之上,通過使用接口和一些框架(如Spring),您可以進(jìn)行自動布線。這大大減少了對較低級別實現(xiàn)類的依賴,使您可以更改低級類而不會影響頂級處理程序。這種類型的應(yīng)用程序設(shè)計是面向服務(wù)的體系結(jié)構(gòu) (SOA) 中的常見做法。


查看完整回答
反對 回復(fù) 2022-09-14
?
蝴蝶不菲

TA貢獻(xiàn)1810條經(jīng)驗 獲得超4個贊

Robert 談到了打破依賴關(guān)系,當(dāng)然你甚至可以打破庫存和汽車之間的依賴關(guān)系,但我認(rèn)為這不會給你帶來太多好處,因為你不會跨越架構(gòu)邊界。


最好將靜態(tài)依賴關(guān)系中斷為 ,因為 I/O 是一個架構(gòu)邊界,然后您可以替換汽車或庫存的打印方式,這對于測試非常有用。System.out


打破靜態(tài)依賴關(guān)系

class Car {

    private String color;

    private Integer numberOfTires;


    private PrintStream output = System.out;


    void setOutput(PrintStream output){

        this.output = Objects.requireNotNull(output);

    }


    public void printCar() {

        output.print("Color: " + color);

        output.print("Number of tires: " + numberOfTires);

    }

}

現(xiàn)在,您可以在測試中替換輸出以捕獲輸出結(jié)果。


應(yīng)用接口隔離原則

public interface Output {

     public void print(String msg);

}



class Car {

    private String color;

    private Integer numberOfTires;


    private Output output = (msg) -> System.out.println(msg);


    void setOutput(Output output){

        this.output = Objects.requireNotNull(output);

    }


    public void printCar() {

        output.print("Color: " + color);

        output.print("Number of tires: " + numberOfTires);

    }

}

現(xiàn)在,您唯一的依賴項是輸出接口,該接口在測試中更容易替換或模擬。


這個小小的變化使您的汽車獨立于具體的輸出系統(tǒng),或者正如羅伯特所說,一個細(xì)節(jié)。我還可以想象實現(xiàn)一個 JTextArea輸出,以便輸出可以顯示在 GUI 中。


干凈的體系結(jié)構(gòu)告訴我們,I/O 是一個細(xì)節(jié),我們的業(yè)務(wù)代碼不應(yīng)該依賴于它。似乎汽車和庫存是您的業(yè)務(wù)代碼,因此我向您展示了如何將其與具體的輸出系統(tǒng)分離 - 一個細(xì)節(jié)。


    +-----+    uses     +--------+     implements   +--------------+

    | Car |  -------->  | Output |  <-------------  | SystemOutput |

    +-----+             +--------+                  +--------------+


             ---------> control flow  ------------->

我們還應(yīng)用了依賴關(guān)系反轉(zhuǎn)原則,因為源代碼依賴關(guān)系指向控制流。


查看完整回答
反對 回復(fù) 2022-09-14
?
紅顏莎娜

TA貢獻(xiàn)1842條經(jīng)驗 獲得超13個贊

據(jù)推測,您的是“車輛庫存”,而不是“一輛汽車和一輛卡車的庫存”。Inventory

考慮到這一點,也許這會有所幫助:

  • Car 是一個 Vehicle

  • Truck 是一個 Vehicle

  • Inventory 取決于 -- 而不是 or ,它對這些類型的一無所知VehicleCarTruck

  • Vehicle::printDetails由 和 實現(xiàn)CarTruck

.

public class Scratch4 {

    public static void main(String args[]) throws Exception {

        Car car = new Car("Blue", 4);

        Truck truck = new Truck();


        Inventory inventory = new Inventory();

        inventory.addVehicle(car);

        inventory.addVehicle(truck);


        inventory.printVehicleDetails();

    }

}


interface Vehicle {

    void printDetails();

}


class Car implements Vehicle {

    private String color;

    private Integer numberOfTires;


    public Car(String color, Integer numberOfTires) {

        this.color = color;

        this.numberOfTires = numberOfTires;

    }


    public void printDetails() {

        System.out.println("Color: " + color);

        System.out.println("Number of tires: " + numberOfTires);

        System.out.println();

    }

}


class Truck implements Vehicle {


    @Override

    public void printDetails() {

        System.out.println("Some kind of truck");

        System.out.println();

    }


}


class Inventory {

    private List<Vehicle> vehicles = new ArrayList<>();;


    public void addVehicle(Vehicle vehicle) {

        vehicles.add(vehicle);

    }


    public void printVehicleDetails() {

        vehicles.forEach(Vehicle::printDetails);

    }

}

收益 率


Color: Blue

Number of tires: 4


Some kind of truck


查看完整回答
反對 回復(fù) 2022-09-14
?
呼啦一陣風(fēng)

TA貢獻(xiàn)1802條經(jīng)驗 獲得超6個贊

在生產(chǎn)環(huán)境中的運行時,B 將使用真正的類 A(或?qū)崿F(xiàn)相同接口的另一個類),因此無需復(fù)制代碼。


使用接口可以將另一個實現(xiàn)用于其他用途,例如,使用內(nèi)存中的輕量級假類 A 進(jìn)行 B 類的單元測試,從而避免重磅實類 A。


您(只能)打破“靜態(tài),構(gòu)建時”的依賴關(guān)系。“動態(tài),運行時”依賴項(始終)保留。


在代碼中:


public interface AInterface {}

public class A implements AInterface {}

public class B {

  AInterface a;

  public B(AInterface a) {

    this.a = a;

  }

}

public class Main {

  B b = B(A());

}

public class AFake implements AInterface {}

public class BTest {

  B b = B(AFake())

}

此示例使用構(gòu)造函數(shù)依賴關(guān)系注入。


查看完整回答
反對 回復(fù) 2022-09-14
  • 4 回答
  • 0 關(guān)注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號