GOF 23设计模式之(结构型模式一)

Posted huangcan1688

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GOF 23设计模式之(结构型模式一)相关的知识,希望对你有一定的参考价值。

目录

1.代理模式

1.1静态代理

1.2动态代理

2.适配器模式

2.1类适配器模式

2.2对象适配器模式

2.3双向适配器模式

3.桥接模式

 

 

一、代理模式(Proxy)

  访问者对象不适合或者不能直接引用目标对象,需要通过代理对象作为访问对象和目标对象之间的中介。并且可以设置一些前置设置、后置处理。通俗来说,代理模式就像生活中的中介。

  可以分为:静态代理、动态代理

  

  核心角色:

  (1)抽象主题类(Subject):通过接口或抽象类声明真实主题和代理对象实现的业务方法

  (2)真实主题类(Real Subject):实现抽象主题中的具体业务,是最终要应用的对象

  (3)代理类(Proxy):提供与真实主题相同的接口,内部好友对真实主题的引用,可以访问、控制、扩展真实主题的功能。

 

  优点:

  (1)代理模式在客户端和目标对象之间起到一个中介和保护目标对象的作用

  (2)代理对象可以扩展目标对象的功能

  (3)代理模式能将客户端与目标对象分离,在一定的程度上降低了系统的耦合度

 

  缺点:

  (1)在客户端和目标对象之间添加代理对象,会造成请求处理速度变慢

  (2)增加了系统的复杂度

 

  静态代理

  技术图片

技术图片
public class textProxy {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //使用代理
        RealSubject cat = new RealSubject();
        Proxy proxy = new Proxy(cat);
        proxy.Request();
        
    }
}

//抽象主题
interface Subject{ //模拟二手汽车交易
    
    public void Request();//封装请求
}

//真实主题
class RealSubject implements Subject{//各地的二手车
    
    //需要代理的对象
    //需要把各地的二手车交给一些代理公司,把我们推销出售汽车
    public void cat() {
        System.out.println("各地二手车");
    }


    @Override
    public void Request() {
        cat();
    }
}

//代理 (中介公司)
class Proxy implements Subject{//找代理

    private RealSubject realSubject;//被代理者
    
    public Proxy(RealSubject realSubject) {
        super();
        this.realSubject = realSubject;
    }
    
    public void setRealSubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }
    
    //代理的工作
    @Override
    public void Request() {
        preRequest();
        realSubject.Request(); //被代理的事情
        postRequest();
    }
    
    //代理前后置设置
    public void preRequest() {
        System.out.println("开始进行代理处理----");
    }
    
    public void postRequest() {
        System.out.println("代理结束处理----");
    }
}
View Code

返回顶部

 

  动态代理

  java中的动态代理,JDK带的动态代理,有两个方法:

  1、java.lang.reflect.Proxy  可以动态的生成代理类和对象。

  2、java.lang.reflect.InvocationHandler(处理器接口)

  可以通过invoke方法实现对真实角色的代理访问。每次通过Proxy生成的代理类和对象时都要指定对应的处理器对象。

  技术图片

 

二、适配器模式(Adapter)

  将一个类的接口转换为客户希望的另外一个接口。Adpater模式使得原来由于接口不兼容而不能一起工作那些类,现在适配为可以一起工作。

  可以分为:类适配器模式、对象适配器模式、双向适配器模式(扩展)

  

  核心角色:

  (1)目标接口(Target):当前系统业务所期待的接口,可以是抽象类或者接口

  (2)适配者类(Adaptee):是被访问和适配的现存组件库的组件接口

  (2)适配器类(Adapter):是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

 

  优点:

  (1)客户端通过适配器可以透明的调用目标接口

  (2)复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类

  (3)将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题

 

  缺点:

  (1)对于适配器来说,更换适配器的实现过程比较复杂

 

  类适配器模式

  技术图片

技术图片
public class textAdapter {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //模拟例子,电脑只有USB接口的,而键盘是圆孔插头的,需要借助转接头
        
        Target tt = new ClassAdapter();
        tt.request(); //这样调用原来USB标识的接口,现在可以输出圆孔接口了。
    }
}

//目标接口  (客户期待适配的接口,就是USB)
interface Target{
    public void request();
}

//适配者类 (相当于圆孔接口)
class Adaptee{
    public void specificRequest() {
        System.out.println("圆孔接口");
    }
}

//适配器类 (相当于转接器,将USB接口,适配输出圆孔接口,这样就可以一起工作了)
class ClassAdapter extends Adaptee implements Target{

    @Override
    public void request() {
        specificRequest(); //适配者类的业务方法
    }
}
View Code

返回顶部

 

  对象适配器模式

  技术图片

技术图片
public class textAdapter {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //模拟例子,电脑只有USB接口的,而键盘是圆孔插头的,需要借助转接头
        Adaptee adaptee = new Adaptee();
        Target tt = new ObjectAdapter(adaptee);
        tt.request(); //这样调用原来USB标识的接口,现在可以输出圆孔接口了。
    }
}

//目标接口  (客户期待适配的接口,就是USB)
interface Target{
    public void request();
}

//适配者类 (相当于圆孔接口)
class Adaptee{
    public void specificRequest() {
        System.out.println("圆孔接口");
    }
}

//适配器类 (相当于转接器,将USB接口,适配输出圆孔接口,这样就可以一起工作了)
class ObjectAdapter implements Target{

    private Adaptee adpaptee;
    public ObjectAdapter(Adaptee adpaptee) {
        this.adpaptee = adpaptee;
    }
    
    @Override
    public void request() {
        adpaptee.specificRequest();
    }
}
View Code

返回顶部

 

  双向适配器模式

  技术图片

技术图片
public class textAdapter {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //模拟例子,电脑只有USB接口的,而键盘是圆孔插头的,需要借助转接头
        //(1) 本来是USB接口的,现在要适配成圆孔接口的
        TwoWayAdaptee adaptee = new AdapteeRealize();//USB接口
        TwoWayTarget target = new TwoWayAdapter(adaptee);
        target.request(); //原来是圆孔接口的   适配后,就可以适配USB接口了
        
        //将现在的圆孔接口适配成USB接口可以用的。
        TargetRealize adaptee2 = new TargetRealize();//圆孔接口
        TwoWayAdaptee target2 = new TwoWayAdapter(adaptee2);
        target2.specificRequest(); //原来是USB接口,适配后圆孔接口

    }
}

//目标接口  (客户期待适配的接口,就是USB)
interface TwoWayTarget{
    public void request();
}

//适配者接口 (相当于圆孔接口)
interface TwoWayAdaptee{
    public void specificRequest();
}

//目标实现类 
class TargetRealize implements TwoWayTarget{

    @Override
    public void request() {
        System.out.println("圆孔接口");
    }
}

//适配者实现类
class AdapteeRealize implements TwoWayAdaptee{

    @Override
    public void specificRequest() {
        System.out.println("USB接口");
    }
}

//双向适配器
class TwoWayAdapter implements TwoWayTarget,TwoWayAdaptee{
    
    private TwoWayTarget target;
    private TwoWayAdaptee adaptee;
    
    //两个构造器。目的是为了可以接受双向输入
    public TwoWayAdapter(TwoWayTarget target) {
        this.target = target;
    }
    public TwoWayAdapter(TwoWayAdaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void specificRequest() {
        target.request();
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
View Code

返回顶部

 

三、桥接模式(Bridge)

  处理多层的继承结构,处理多维度变化的场景,将各个维度设置成独立的继承结构,使维度可以独立的扩展在抽象层建立关联。从而降低了抽象和实现这两个可变维度的耦合度。主要特点是,取消多继承,解决多维度的问题。

  

  核心角色:

  (1)抽象化角色(Abstraction):定义抽象类,并包含一个对实例化对象的引用。

  (2)扩展抽象化角色(Refined Abstraction):是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。

  (3)实现化角色(Implementor):定义实现化角色的接口,供扩展抽象化角色调用。

  (4)具体实现化(Concrete Implementor):给出实现化角色接口的具体实现。

 

  优点:

  (1)由于抽象与实现分离,所有扩展能力强。

  (2)其实现细节对客户透明。

 

  缺点:

  (1)由于聚合关系在抽象层,要求开发者针对抽象化进行设计与编程,增加了系统的理解和设计难度。

 

  技术图片

技术图片
public class textBridge {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //模拟:电脑有分品牌、分台式笔记本、配置等等。(涉及到多维度)
        
        Implementor imple = new ConcreatelmplementorA();//创建第一个品牌
        Abstraction abs = new RefinedAbstraction(imple);
        abs.Operation();
        
        
    }
}



//实现化角色。
interface Implementor{//品牌
    public void Operationlmpl();
}

//具体实现化角色
class ConcreatelmplementorA implements Implementor{ //联想品牌

    @Override
    public void Operationlmpl() {
        System.out.println("联想");
    }
}

class ConcreatelmplementorB implements Implementor{//宏基品牌

    @Override
    public void Operationlmpl() {
        System.out.println("宏基");
    }
}

//抽象化角色
abstract class Abstraction{//电脑的台式或笔记本
    
    protected Implementor imple;//为了子类可以使用

    protected Abstraction(Implementor imple) {
        this.imple = imple;
    }
    
    public abstract void Operation();//得到实现化角色的品牌
}

//扩展抽象化角色
class RefinedAbstraction extends Abstraction{

    protected RefinedAbstraction(Implementor imple) {
        super(imple);
    }

    @Override
    public void Operation() {
        imple.Operationlmpl();//一个维度:品牌
        System.out.println("台式机");//当前扩展一个维度:表现形式
    }
}
View Code

返回顶部

 

    

 

以上是关于GOF 23设计模式之(结构型模式一)的主要内容,如果未能解决你的问题,请参考以下文章

GOF23设计模式之迭代器模式(iterator)

GOF23设计模式之模板方法模式(template method)

GOF23设计模式之组合模式(composite)

GOF 23设计模式之(行为型模式一)

GOF23设计模式之适配器模式

GOF23设计模式之单例模式