zoukankan      html  css  js  c++  java
  • Java经典23种设计模式之结构型模式(一)

    结构型模式包含7种:适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式。

    本文主要介绍适配器模式和桥接模式。

    一、适配器模式(Adapter)

    适配器模式事实上非常easy。就像手机充电器一样,手机须要5V的。而插座出来是220V。

    因此须要充电器变压就ok。

    再比方。一个之会说汉语的和一个仅仅会说英语的无法沟通。那就中间请个翻译。全部的交流通过翻译。翻译翻给会说英语的,就能完毕一次单项交流的。链接1 中的样例非常生动形象了。总结一下,无非就是有个通用的接口(称为Target),假设一切顺利的话大家相安无事,不须要适配。

    假设某个接口不是通用的标准接口,则需在实现Target时,又一次new一个非标准接口的变量。然后利用Target提供的函数。在函数体里把非标准接口的对象的函数调用一下,如同移花接木一样。

    以下附详细说明:

    1、Target

    public interface Target {
        void adapteeMethod();
        void adapterMethod();
    }

    2、Adaptee 
    public class Adaptee {
        public void adapteeMethod() {
            Syste*.out.p*intln("Adaptee method!");
        }
    }

    这就是上面文中说的那个非标准接口的类。

    3、Adapter

    public clas* Adapter implement* Target {
        private Adap*ee adaptee;
        public Adapter(Adaptee adaptee) {
            this.adapte* = adaptee;
        }
    public void adapteeMethod() {
    adaptee.adapteeMethod();
    }
    public void adapterMethod() {
    *ystem.out.println("Adapter method!");
        }
    }能够看到在适配器里,new了一个Adaptee变量,然后再通用标准接口Target里的函数里。调用adaptee.***。

    測试代码:

    public class Test {
        public static void main(String[] args) {
            Target target = new Adapter(new Adaptee());
            target.adapteeMethod();
            target.adapterMethod();
        }
    }

    适用性:

        1.你想使*一个已经存在的类。而它的接口不符合你的需求。


        2.你想创建一个能够复用的类,该类能够与其它不相关的类或不可预见的类(即那*接口
          可能不一定兼容的类)协同工作。
        3.(仅适用于对象Adapter)你想使用一些已经存在的子类,可是不可能对每个都进行
          子类化以匹配它们的接口。对象适配器能够适配它的父类接口。

    二、桥接模式(Bridge)

    桥接模式是为了将抽象部分和实现部分分离,假设一个事务有多个维度决定。则须要使用桥接模式解耦。举个样例,路有一般的公路和快速公路两种。车有小汽车和大卡车两种。这样两两组合在一起有四种情况。为了描写叙述清晰什么车在什么路上须要设计四个类。假设用桥接模式就非常easy了,桥接模式的精髓在于在当中一个类里要维护一个另外一个类的对象。比方我再定义“路”的时候,里面设计个变量Car(这是个基类,它的子类为小汽车和卡车)。

    这样通过继承“路”这个虚类,得到两个详细的路:一般公路和快速公路。

    继承虚类Car。得到两个详细的车:小汽车和大卡车。这样在描写叙述事物时。我通过Car c = new 快速公路,然后对c里的Car这个变量进行赋值为 小汽车和大卡车,就能清晰描写叙述事物了。

    假设再复杂一点,上面样例仅仅有两个维度:路和汽车,再加一个维度:人。当然人有男人、女人。

    那么为了逻辑上的观念和现实一致,能够再定义虚类人的时候,定义一个成员变量Car。在定义虚类Car时。里面加个成员变量Way。这样假设事物有A、B、C、D。

    。。若干个维度,仅仅需在A定义时添加一个虚类B的成员变量。定义B时添加一个C的成员变量,以此类推,这就是桥接模式。能够看链接里的样例是用C++写的,等有时间我用java写个。以下再附个男人女人穿马夹和裤子的样例。典型的两个维度:

    1.Abstraction 抽象类people,维护一个指向Implementor类型对象的指针。这里就是指后面的衣服虚类

    public abstract class Person {
        private Clothing clothing;
        pr*vate String type;
        public Clothing getClothing() {
            return clothing;
        }
        publi* void setClothing() {
            this.clothing = *lothingFactory.getClothing();
        }
        public void setType(String type) {
            t*is.type = type;
        }
        public String getType() {
            return this.ty*e;
        }
        public abstract void dress();
    }

    2、RefinedAbstraction :扩充由Abstraction定义的接口。

    男人类
    public class Man extends *erson {
        public Man() {
            setType("男人");
        }
        public void dress() {
            Clothing clothing = get*lothing();
            clothing.personDressCloth(this);
        }
    }

    女人类:

    public class Lady extends Person {


        public Lady() {
            setTyp*("女人");
        }
        
        public void dress() {
            Cloth*ng clothing = getClothing();
            c*othing.personDressCloth(this);
        }
    }

    3、Implementor
    定义实现类的接口,该接口不一定要与Ab*traction的接口全然一致。事实上这两个接口能够全然不同。
    一般来讲。Implementor接口仅提供基本操作。而Abstraction则定义了基于这些基本操作的较高层次的操作。

    public abstract class Clothing {
        public abstract void personDressC*oth(*erson person);
    }

    4、详细的ConcreteImplemento* 

    public class Jackt extends Clothing {


        public void personDressCloth(Person person) {
            System.out.println(person.getType() + "穿马甲");
        }
    }
    public class Trouser extends Clothing {


        public void personDressCloth(Person person) {
            System.ou*.println(*erson.getType() + "穿裤子");
        }
    }

    測试代码:

    public class Test {
        public static void main(String[] args) {
            Person man = new Man();
            Person lady = new Lady();
            Clothing jacket = new Jacket();
            Clothing trouser = new Trouser();
            jacket.personDressCloth(man);
            trouser.personDressCloth(man);
            jacket.personDressCloth(lady);
            trouser.personDressCloth(lady);
        }
    }
    

    哈哈,后来找了下,http://blog.csdn.net/jason0539/article/details/22568865已经将上面人、路、车的样例用Java写出来了。能够參考下。但文中。使用人中有路。路上有车的构造思想不太推荐,另外就是没使用Interface感觉还是有点小乱,不清晰。

    另外就是这个人、车、路的样例在构建上是单向的,这个比較好,new出来一个人,然后set一下什么路。

    而穿衣服的样例是个双向耦合的,在Clothing里须要传递People虚类,好在耦合的都是虚类。事实上,也能够看成是单向耦合的。在Pepple里事实上定义了dress方法,通过前面说的创建型模式获得须要的Clothing类型就ok了。

  • 相关阅读:
    Http协议的断点续传下载器,使用观察者模式监视下载进度,使用xml保存下载进度。
    C++ 复制到粘贴板
    编译防火墙——C++的Pimpl惯用法解析
    字符串输出
    windows路径操作API函数
    Boost解析xml——xml写入
    智能指针shared_ptr
    Boost 解析xml——插入Item
    ListCtrl添加右键菜单(在对话框类中)
    抓包工具Charles的使用说明
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5199816.html
Copyright © 2011-2022 走看看