七大原则之二:依赖倒置原则

故事的开始

每位小朋友从小都有一个伟大而纯真的梦想。而我阿菜也不例外,哈哈哈,为了配合我吃货的人设,我从小的理想就是可以开一家奶茶店,因为可以赚钱,又可以吃吃吃。。。想想都幸福。嘻嘻~

小阿菜想我的店要开在转角处,买些小帐篷,来的客人们可以小帐篷的小空间里倾倾计,拍拍照。对了我还需要一个点餐的机器。每当客人下单的时候,就打印出下单的奶茶信息。这个怎么实现呢?看看下面的伪代码

小菜的猜想实现1

1.定义一个柜台类,该类中实现了对不同奶茶的打印信息的方法:代码中简单打印了一条语句,真实的业务肯定比这个复杂多了。

/** * @Description: 模拟点餐的柜台类 */
public class Counter {

    void sellCheeseCheeseBerries(){
        System.out.println("客官 点了一杯芝莓果奶茶");
    }

    void sellBobo(){
        System.out.println("客官 点了一杯BOBO奶茶");
    }

    void sellCheeseRuby(){
        System.out.println("客官 点了一杯芝士红玉奶茶");
    }
    
}

2.定义一个客户端类,模拟用户下单时,对柜台的调用。

public class Client {

    public static void main(String[] args) {
        Counter counter = new Counter();
        counter.sellBobo();
        counter.sellCheeseCheeseBerries();
        counter.sellCheeseRuby();
    }
}

结果,没什么意外运行结果如下:

客官 点了一杯BOBO奶茶
客官 点了一杯芝莓果奶茶
客官 点了一杯芝士红玉奶茶

虽然结果是达到了,但是以后每添加一种奶茶的时候,都需修改Counter 类,在类中加入对应实现方法。很明显我们的高层中的客户端类Client 和底层的Counter 类是强耦合的也就就是说Client 依赖于Counter 的。
小菜面向实现编程真实简单暴力,但是真的不利于我们后续的扩展。为了减少哦类之间偶尔性试试面向接口编程

小菜的猜想实现2

1.定义一个奶茶接口,接口中定义了一个销售奶茶时的方法。至于具体的实现,就留给了实现了。

/** * @Description: 定义基层的接口 */
public interface IMilkTea {

    /** * 奶茶售卖接口方法的定义 */
    void sell();
}

2.接口的实现类
2.1芝芝莓果奶茶类

public class CheeseCheeseBerries implements  IMilkTea {

    /** * 芝芝莓果奶茶 */
    public void sell() {
        System.out.println("客官 点了一杯芝莓果奶茶");
    }
}

2.2:Bobo奶茶类

public class Bobo implements IMilkTea {
    /** * BObo奶茶 */
    public void sell() {
        System.out.println("客官 点了一杯BOBO奶茶");
    }
}

2.3:芝士红玉

public class sellCheeseRuby implements IMilkTea {
    /** * 杯芝士红玉 */
    public void sell() {
        System.out.println("客官 点了一杯芝士红玉奶茶");
    }
}

模拟客户端的调用

    @Test
    public void  test1(){
        CounterNew counterNew = new CounterNew();
        //点一份芝芝莓果
        CheeseCheeseBerries cheeseCheeseBerries = new CheeseCheeseBerries();
        counterNew.sellMilk(cheeseCheeseBerries);

        //点一份bobo奶茶
        Bobo bobo = new Bobo();
        counterNew.sellMilk(bobo);

        //点一份杯芝士红玉
        CheeseRuby cheeseRuby = new CheeseRuby();
        counterNew.sellMilk(cheeseRuby);

    }

这样即得到了理想中的运行结果,通过如果后续有新的奶茶品种需要添加的时候。那么只是需要,新增一个接口的实现类。

通过构造注入形式传递参数

public class CounterNew {

    private IMilkTea milkTea;

    public CounterNew(IMilkTea milkTea) {
        this.milkTea = milkTea;
    }

    void sellMilk(){
        milkTea.sell();
    }
}
 /** * 通过构造注入的方式传递参数 */
    @Test
    public void  test2(){
        //点一份芝芝莓果
        CounterNew counterNew1 = new CounterNew(new CheeseCheeseBerries());
        counterNew1.sellMilk();

        //点一份bobo奶茶
        CounterNew counterNew2 = new CounterNew(new  Bobo());
        counterNew2.sellMilk();

        //点一份杯芝士红玉
        CounterNew counterNew3 = new CounterNew(new CheeseRuby());
        counterNew3.sellMilk();
    }

通过setting注入

public class CounterNew {

    private IMilkTea milkTea;

    public void setMilkTea(IMilkTea milkTea) {
        this.milkTea = milkTea;
    }

    void sellMilk(){
        milkTea.sell();
    }
}
 @Test
    public void test3(){
        CounterNew counterNew = new CounterNew();
        //点一份芝芝莓果
        counterNew.setMilkTea(new CheeseCheeseBerries() );
        counterNew.sellMilk();

        //点一份bobo奶茶
        counterNew.setMilkTea(new Bobo());
        counterNew.sellMilk();

        //点一份杯芝士红玉
        counterNew.setMilkTea(new CheeseRuby());
        counterNew.sellMilk();
    }

edit time
1.2018-12-02 17:58
location:GZ

你可能感兴趣的:(设计模式)