zoukankan      html  css  js  c++  java
  • java 实现Bridge模式(转)

    原文:http://chjking.blog.163.com/blog/static/6439511120081152534252/

    看了网上一些关于咖啡加奶的例子,觉得真是天下文章一大抄,不管好的坏的都照搬,于是在原有的基础上进行了重新编写,代码也已经过测试。

    Bridge定义 :
    将抽象和行为划分开来,各自独立,但能动态地结合。

    这句话是对的,但理解起来较为困难。可以这么理解,抽象是一个事物的本身的特征,行为是一个事物可以做的动作,特征是相对独享的,行为是可以共享的。举例:不同的数据库,它们具有不同的特征,比如URL,驱动这些每个数据库都不能共享,就是所谓抽象。而每个数据库都具有类似的行为,插入,删除,修改等等,这些操作是可以和共享的,就是所谓行为。

    为什么使用?

    一句话可以概括,解耦合。

    以数据库为例,当使用不同数据库时,不需要对其行为部分代码进行修改,当添加新的行为时,也不需要对数据库特征部分进行修改,就可以使所有存在数据库共享这一行为。

    如何实现?

    以下代码改编自网上:

    一杯咖啡为例,有中杯和大杯之分,同时还有加奶 不加奶之分. 假如用单纯的继续,这四个具体实现(中杯 大杯 加奶 不加奶)之间有概念重叠,因为有中杯加奶,也有中杯不加奶, 假如再在中杯这一层再实现两个继续,很显然混乱,扩展性极差.那我们使用Bridge模式来实现它.

    首先是咖啡可以进行的行为的父接口:(加奶,不加奶)

    public interface CoffeeImpl {
         public String pourCoffeeImpl();
    }

    下面两个是行为的具体的实现子类

    加奶

    public class MilkCoffeeImpl implements CoffeeImpl {

         public String pourCoffeeImpl() {
              System.out.println("add milk");
              return "add milk";
         }

    }

    不加奶

    public class FragrantCoffeeImpl implements CoffeeImpl {

         public String pourCoffeeImpl() {
              System.out.println("no milk");
              return "no milk";
         }

    }

    下面是咖啡的抽象父类,也就是区分大杯和中杯

    public abstract class Coffee {
         CoffeeImpl coffeeImpl;

         public CoffeeImpl getCoffeeImpl() {
              return coffeeImpl;
         }

         public void setCoffeeImpl(String way) {
              this.coffeeImpl = ActionFactory.createCoffeeImpl(way);
         }
     
         public abstract void pourCoffee();
    }

    下面是2个抽象的具体实现子类

    大杯

    public class BigCoffee extends Coffee {
     
         public BigCoffee(String way) {
              pourCoffee();
              this.setCoffeeImpl(way);
              this.coffeeImpl.pourCoffeeImpl();
         }
     
         @Override
         public void pourCoffee() {
              System.out.print("Big coffee ");
         }

    }

    中杯

    public class MiddleCoffee extends Coffee {
     
         public MiddleCoffee(String way) {
              pourCoffee();
              this.setCoffeeImpl(way);
              this.coffeeImpl.pourCoffeeImpl();
         }

         @Override
         public void pourCoffee() {
              System.out.print("Middle coffee ");
         }

    }

    下面是一个简单工厂,用来动态确定咖啡的行为,究竟是加奶还是不加奶,当然可以使用自己定义的方法来实现这个功能,这里我选择简单工厂。

    public class ActionFactory {
         public static CoffeeImpl createCoffeeImpl(String way) {
              if("milk".equals(way)) {
                   return new MilkCoffeeImpl();
              } else if("fragrant".equals(way)) {
                   return new FragrantCoffeeImpl();
              } else {
                   return null;
              }
         }   
    }

    到此为止,bridge模式就完成了,读者可以很方便的自己试试着这个基础上添加自己的咖啡抽象,比如小杯咖啡,还能添加咖啡行为,比如加糖不加糖,记得需要对简单工厂进行修改。

    最后就是测试类

    public class Test {

     /**
      * @param args
      */
     public static void main(String[] args) {
           //中杯不加奶
          Coffee coffee1 = new MiddleCoffee("fragrant");
          //大杯加奶
          Coffee coffee2 = new BigCoffee("milk");
          //中杯加奶
          Coffee coffee3 = new MiddleCoffee("milk");
          //大杯不加奶
          Coffee coffee4 = new BigCoffee("fragrant");
     }

    }

    完成了,输出结果是:

    Middle coffee no milk
    Big coffee add milk
    Middle coffee add milk
    Big coffee no milk

    可以看到调用很方便,类决定了什么样的咖啡(抽象),而参数决定了什么样的操作(行为)。

  • 相关阅读:
    MHA自动切换流程
    手写源码之 简单实现on emit off
    手写源码 -- bind,call,aplly
    多维数组转化为一维数组
    electron+vue中使用nodeJs的fs模块以及上传文件
    制作海报
    vue中引入播放器(百度播放器和腾讯云播放器)
    webpack配置
    webpack
    css样式
  • 原文地址:https://www.cnblogs.com/fillPv/p/5110059.html
Copyright © 2011-2022 走看看