zoukankan      html  css  js  c++  java
  • Bridge

    解决什么问题

      以下两句话是从Wikipedia上抄的,我觉得总结得很到位:

    • An abstraction and its implementation should be defined and extended independently from each other.
    • A compile-time binding between an abstraction and its implementation should be avoided so that an implementation can be selected at run-time.

      我觉得Design Patterns: Elements of Reusable Object-Oriented Software 这本书上关于Bridge模式的例子举得不是很好。我来举个例子。

      我们都知道,自然界有雄性和雌性两种性别;也有幼年,中年,老年三种年龄。我们现在来定义一个人,在性别和年龄纬度下,我们可以定义出六个类,分别是:男孩(幼年雄性),女孩(幼年雌性),男人(中年雄性),女人(中年雌性),老头(老年雄性),老太(老年雌性)。类的继承关系是这样的:

      

      这样做的问题是抽象和实现在编译期就绑定了,什么意思呢?设想一下我们想把年龄再扩展以下,搞个青年出来,那么我们又得实现两个类:男青年,女青年,这两个类编写出来的时候,它们的getAge一定返回"teenager"。我想把Age和Sex的概念,复用到其他类上,也是不可能的。它们和Person绑死了。

      Bridge模式怎么解决这个问题呢?把继承的多态,化为属性的多态。把性别和年龄这两个类和Person剥离开,让它们成为Person的属性,这样我们就不用搞这么多类,我们只需要一个Person类就好了,至于我们到底要男孩还是男人,给Male和Age这两个属性赋值就好了,这就是动态决定了抽象和实现的关系。这里的抽象是Person,而实现是Male和Age。  

      继承可以解决多态的问题,组合也可以解决多态的问题。我们更加Prefer组合,因为组合更灵活。我们的Sex类和Age类还可以复用到 马,牛上,但是用Boy就写死了Sex, Age与Person的关系。

      Bridge模式下,类的关系如下图:

      

    代码(Java)

    package com.mycompany.business.bridge;
    
    public class Person {
        private Age age;
        private Sex sex;
    
        public Person(Age age, Sex sex){
            this.age = age;
            this.sex = sex;
        }
    
        public String getAge(){
            return this.age.getAge();
        }
    
        public String getSex(){
            return this.sex.getSex();
        }
    
    }
    package com.mycompany.business.bridge;
    
    public interface Age {
        String getAge();
    }
    package com.mycompany.business.bridge;
    
    public interface Sex {
        String getSex();
    }
    package com.mycompany.business.bridge;
    
    public class Female implements Sex {
        public String getSex() {
            return "I am female";
        }
    }
    package com.mycompany.business.bridge;
    
    public class Male implements Sex {
        public String getSex() {
            return "I am male";
        }
    }
    package com.mycompany.business.bridge;
    
    public class Young implements Age{
    
        public String getAge() {
            return "I am young";
        }
    }
    package com.mycompany.business.bridge;
    
    public class MiddleAge implements Age {
        public String getAge() {
            return "I am middle-age";
        }
    }
    package com.mycompany.business.bridge;
    
    public class Old implements Age {
        public String getAge() {
            return "I am old";
        }
    }
    package com.mycompany.business.bridge;
    
    public class BootStrap {
        public static void main(String[] arge){
            Person person = new Person(new Young(), new Male());
            System.out.println(person.getAge());
            System.out.println(person.getSex());
        }
    }

      

  • 相关阅读:
    沙盒解决方案part1:沙盒解决方案的用途和好处
    session定义使用和丢失问题小结(20120101有更新&&20121026又更)
    普通pc检测维修的一个特例:检测\换板\电源\IDE信道\声卡驱动
    用户sa登录失败,该用户与可信sql server连接无关联
    trycatchfinally(C# 简单学习)
    按钮只能一次提交:ajax页面中调用ascx控件,如何设置ascx中按钮为false
    开始学习:Ajax的全称是:AsynchronousJavaScript+XML
    ajax学习的第一次亲密接触.(虽然还有一点模糊)
    .net2.0 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的
    创建可重复使用的控件ascx-一页只能有一个服务器端 Form 标记?
  • 原文地址:https://www.cnblogs.com/johnsblog/p/10366142.html
Copyright © 2011-2022 走看看