Java经典23种设计模式之结构型模式(一)

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

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

一、适配器模式(Adapter)

适配器模式其实很简单,就像手机充电器一样,手机需要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)

桥接模式是为了将抽象部分和实现部分分离,如果一个事务有多个维度决定,则需要使用桥接模式解耦。举个例子,路有一般的公路和高速公路两种。车有小汽车和大卡车两种。这样两两组合在一起有四种情况,为了描述清楚什么车在什么路上需要设计四个类。如果用桥接模式就很简单了,桥接模式的精髓在于在其中一个类里要维护一个另外一个类的对象。比如我再定义“路”的时候,里面设计个变量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种设计模式之结构型模式(一)

时间: 2024-12-24 16:41:58

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

Java经典23种设计模式之结构型模式(二)

接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和组合对象的使用具有一致性.单看这句话貌似有点抽象,其实比较简单. 以李云龙的独立团为例,目的要统计赵嘉宇一战共歼灭敌人多少个.最高的级别是团,一个团有若干个营,一个营有若干个排,一个排有若干个战士.(为了简化问题,排下面就不设行政单位了).很自然的,李云龙给营长开会回去给老子统计.营长回去给各个排长开会,赶紧

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

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

本文接着介绍11种行为型模式里的备忘录模式.观察者模式.状态模式. 一.备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态.还是比较好理解的. 1.Memento 备忘录存储原发器对象的内部状态,这个类就是要存储的对象的状态.状态需要多少个变量,在Memento里就写多少个变量. public class Memento { private String state; public Meme*to(String st

Java经典23种设计模式之行为型模式(一)

行为型设计模式有11种,分别是Chain of Responsibility ( 责任链模式 ).Command ( 命令模式 ).Interpreter ( 解释器模式 ) .Iterator ( 迭代器模式 ).Mediator ( 中介者模式 ) .Memento ( 备忘录模式 ) .Observer ( 观察者模式 ).State ( 状态模式 ) .Strategy ( 策略模式 ).TemplateMethod ( 模板方法 ).Visitor ( 访问者模式 ),本文介绍这11种

Java经典23种设计模式之行为型模式(四)

本文介绍11种行为型设计模式里的策略模式.模板方法.访问者模式. 一.策略模式 定义一系列的算法,把它们每个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 1.Strategy定义所有支持的算法的公共接口.Context使用这个接口来调用某ConcreteStrategy定义的算法. public abstract class Strategy {    public abstract void method();} 2.ConcreteStrategy以Strate

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

本文接着介绍行为型模式里的解释器模式.迭代器模式.中介者模式. 一.解释器模式Interpret 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的中的句子. 1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中全部的节点所共享. public abstract class Expression {    abstract void interpret(Context ctx);} 2.Expression

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

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

设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计模式有23种,分三个大类型: 创建型模式(5) .结构型模式(7).行为型模式(11),5 + 7 +11 = 23.网上一搜也都是一大把了,这里不过个人作的记录.本文记录创造型模式里的工厂方法(Factory Method).抽象工厂(Abstract Factory).单例模式这三种.力求透彻.

java中23种设计模式之13-组合模式(composite pattern)

import java.util.LinkedList;abstract class Company{ private String name; public void setName(String name) { this.name=name; } public String getName() { return name; } abstract void add(Company company); abstract void remove(Company company); abstract