结构型模式包含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了。

Java经典23种设计模式之结构型模式(一)的更多相关文章

  1. Go语言实现的23种设计模式之结构型模式

    摘要:本文主要聚焦在结构型模式(Structural Pattern)上,其主要思想是将多个对象组装成较大的结构,并同时保持结构的灵活和高效,从程序的结构上解决模块之间的耦合问题. 本文分享自华为云社 ...

  2. GoF的23种设计模式之结构型模式的特点和分类

    结构型模式描述如何将类或对象按某种布局组成更大的结构.它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象. 由于组合关系或聚合关系比继承关系耦合度低,满足 ...

  3. Java经典23种设计模式之行为型模式(二)

    本文接着介绍行为型模式里的解释器模式.迭代器模式.中介者模式. 一.解释器模式Interpret 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的中的句子. 1 ...

  4. Java经典23种设计模式之行为型模式(三)

    本文接着介绍11种行为型模式里的备忘录模式.观察者模式.状态模式. 一.备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态.这样以后就能够将该对象恢复到原先保存的状 ...

  5. Java经典23种设计模式之创造型模式(一)

    设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计 ...

  6. GoF23种设计模式之结构型模式之组合模式

    一.概述 将对象组合成树型结构以表示“部分--整体”的层次关系.组合模式使得用户对单个对象和组合对象的使用具有一致性. 二.适用性 1.你想表示对象的部分--整体层次结构的时候. 2.你希望用户忽略组 ...

  7. GoF23种设计模式之结构型模式之代理模式

    一.概述 为其他对象提供一种代理以控制对这个对象的访问. 二.适用性 1.远程代理(RemoteProxy):为一个对象在不同的地址空间土工局部代表. 2.虚代理(VirtualProxy):根据需要 ...

  8. GoF23种设计模式之结构型模式之享元模式

    一.概述  运用共享技术有效地支持大量细粒度的对象. 二.适用性 1.当一个应用程序使用了大量的对象的时候. 2.由于使用大量的独享而造成很大的存储开销的时候. 3.对象的大多数状态都可变为外部状态的 ...

  9. GoF23种设计模式之结构型模式之桥接模式

    一.概述         将类的抽象部分与实现分部分离开来,使它们都可以独立地变化. 二.适用性 1.你不希望在抽象和实现之间有一个固定的绑定关系的时候.例如:在程序运行时实现部分应可以被选择或切换. ...

随机推荐

  1. Oracle order by case when 多条件排序

    ORACLE sql 排序 根据两个条件排序,根据id号由小到大排序,同时country字段是北京的排最前面前面,其次上海,..大连,最后是其他城市,怎么写? 写法如下:select * from p ...

  2. iOS开发 UITableView之cell

    1.cell简介 UITableView的每一行都是一个UITableViewCell,通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行 U ...

  3. USACO5.4-TeleCowmunication

    题目大意:给出一个无向图,要求删除尽量少的点,使给定的2点间不再连通,并输出字典序最小的方案题型:图论-网络流此题难点在于建图,后面就是套网络流的模板.将点看成边,例如第i个点可以看成一条有向边< ...

  4. 【USACO 1.4.1】铺放矩形块

    [描述] 给定4个矩形块,找出一个最小的封闭矩形将这4个矩形块放入,但不得相互重叠.所谓最小矩形指该矩形面积最小.               所有4个矩形块的边都与封闭矩形的边相平行,图1示出了铺放 ...

  5. centos账户管理命令(root权限)

    cat /etc/passwd | grep -v /sbin/nologin | cut -d : -f 1        查看所有用户 userdel -r 用户名           -删除用户 ...

  6. jQuery实现checkbox全选反选及删除等操作

    1.list.html 说明:用checkbox数组Check[]存放每一行的ID值 <div id="con"> <table width="100% ...

  7. JavaScript-学习一字符串

    字符串可以存储一系列字符,如 "John Doe". 字符串可以是插入到引号中的任何字符.你可以使用单引号或双引号: 用于字符串的 + 运算符 + 运算符用于把文本值或字符串变量加 ...

  8. python 文件系统

  9. js性能优化--学习笔记

    <高性能网站建设进阶指南>: 1.使用局部变量,避免深入作用域查找,局部变量是读写速度最快的:把函数中使用次数超过一次的对象属性和数组存储为局部变量是一个好方法:比如for循环中的.len ...

  10. git config --global core.excludesfile配置gitignore全局文件

    Linux中,这时把全局要忽略的文件列表.gitignore放当前用户根目录下: git config --global core.excludesfile '~/.gitignogtire' Win ...