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了。

  • 相关阅读:
    二进制位运算
    Leetcode 373. Find K Pairs with Smallest Sums
    priority_queue的用法
    Leetcode 110. Balanced Binary Tree
    Leetcode 104. Maximum Depth of Binary Tree
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 64. Minimum Path Sum
    Leetcode 63. Unique Paths II
    经典的递归练习
    案例:java中的基本排序
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5199816.html
Copyright © 2011-2022 走看看