zoukankan      html  css  js  c++  java
  • 软件设计模式修炼 -- 桥接模式


    桥接模式用一种很巧妙的方式处理继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效地控制了系统中类的个数。


    模式动机

    设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要四个形状类,如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有两种设计方案:第一种是为每一个行政都提供一套各种颜色的版本,这种方案使用的是多级继承结构,如果有四种形状,十二种颜色,则我们需要四十八个类。如果要增加新形状则同时也要具备所有的颜色,增加新的颜色也要为所有的形状添加对应颜色的子类;第二种提供四个形状类、十二种颜色类,根据实际对形状和颜色进行组合,此时系统中的类是十六个。如需增加新的形状或颜色,只需再增加一个新的形状类或颜色类即可。

    很明显,对于有两个变化维度(即两个变化的原因)的系统,采用方案二可以使系统中类的个数更少,且系统扩展更为方便。


    模式定义

    将抽象部分与它的实现部分分离,使它们都可以独立地变化


    模式结构

    在这里插入图片描述

    桥接模式包含如下几个角色:

    1. Abstraction(抽象类)

      用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义一个Implementor类型对象使其与implementor之间具有关联关系,它可以包含抽象的业务方法,还可以包含具体的业务方法。

    2. RefineAbstraction(扩充抽象类)

      扩充由Abstraction定义的接口,通常情况下是具体类,实现在Abstraction中定义的抽象业务方法,在RefineAbstraction可以调用Implementor中定义的业务方法。

    3. Implementor(实现类接口)

      对一些基本操作进行了定义,而具体实现交给其子类。

    4. ConcreteImplementorA(具体实现类)

      实现Implementor接口并且具体实现它,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时ConcreteImplementor对象将替换其父类对象,提供给客户具体的业务操作方法。


    桥接模式实例之模拟毛笔

    1. 实例说明

      现需提供大小两种型号的画笔,能绘制三种不同的颜色,只需五个类就能实现功能。

    2. 实例代码及解释

      1. 实现类接口Color

        public interface Color {
        
            void bepaint(String penType, String name);
        }
        
      2. 具体实现类Red

        public class Red implements Color {
        
            @Override
            public void bepaint(String penType, String name) {
                System.out.println(penType + "红色的" + name);
            }
        }
        
      3. 具体实现类Green

        public class Green implements Color {
        
            @Override
            public void bepaint(String penType, String name) {
                System.out.println(penType + "绿色的" + name);
            }
        }
        
      4. 具体实现类Blue

        public class Blue implements Color {
        
            @Override
            public void bepaint(String penType, String name) {
                System.out.println(penType + "蓝色的" + name);
            }
        }
        
      5. 抽象类Pen

        public abstract class Pen {
        
            protected Color color;
        
            public void setColor(Color color) {
                this.color = color;
            }
        
            public abstract void draw(String name);
        }
        
      6. 扩充抽象类BigPen

        public class BigPen extends Pen {
        
            @Override
            public void draw(String name) {
                String penType = "大号毛笔绘制";
                this.color.bepaint(penType, name);
            }
        }
        
      7. 扩充抽象类SmallPen

        public class SmallPen extends Pen {
        
            @Override
            public void draw(String name) {
                String penType = "小号毛笔绘制";
                this.color.bepaint(penType, name);
            }
        }
        
      8. XML操作工具

        public class XMLUtilPen {
        
            public static Object getBean(String args) {
        
                try {
                    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        
                    Document document = documentBuilder.parse(new File("configPen.xml"));
                    NodeList nodeList = document.getElementsByTagName("className");
                    Node classNode = null;
        
                    if (args.equals("color")) {
                        classNode = nodeList.item(0).getFirstChild();
                    } else if (args.equals("pen")) {
                        classNode = nodeList.item(1).getFirstChild();
                    }
        
                    String cName = classNode.getNodeValue();
        
                    Class c = Class.forName("com.bridgePattern." + cName);
                    Object o = c.newInstance();
                    return o;
        
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
        
            }
        }
        
      9. 客户端测试类Client

        public class Client {
        
            public static void main(String[] args) {
        
                Color color = (Color) XMLUtilPen.getBean("color");
                Pen pen = (Pen) XMLUtilPen.getBean("pen");
        
                pen.setColor(color);
                pen.draw("桃花");
            }
        }
        
      10. 结果分析

        如果在配置文件将第一个节点中内容设置为 Red,第一个节点中内容设置为 BigPen,则输出结果如下:
        在这里插入图片描述
        如果在配置文件将第一个节点中内容设置为 Blue,第一个节点中内容设置为 SmallPen,则输出结果如下:
        在这里插入图片描述
        如果需要增加新的毛笔或颜色,只需增加对应的扩充抽象类或具体实现类即可。在使用桥接模式设计的系统中,无论是哪个维度的扩展,对原有代码都无须修改,且更换具体类只需修改配置文件,桥接模式通过抽象方法耦合,使得系统具有良好的扩展能力。


  • 相关阅读:
    [洛谷P1155] 双栈排序
    [洛谷P4315] 月下”毛景“树
    [洛谷P2486] [SDOI2011]染色
    [HNOI2010] 弾飞绵羊
    mysql注入总结
    cisco交换机实现端口聚合
    python为运维人员打造一个监控脚本
    复习ACCESS注入
    利用sfc文件构建网络渗透
    FTP站点设置
  • 原文地址:https://www.cnblogs.com/Yee-Q/p/12487976.html
Copyright © 2011-2022 走看看