www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

Java的结构型情势计算机编程,设计格局

2019-11-24 02:18 来源:未知

适配器-桥接-外观(Adapter-Bridge-Facade)

模式定义

外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

Java的结构型模式,Java结构型模式

结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与类的实例。故可以分为类结构模式和对象结构模式。

在GoF设计模式中,结构型模式有:
1.适配器模式 Adapter
   适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
   两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以就需要一个适配器来完成衔接过程。

2.桥接模式 Bridge
   桥接模式将抽象部分与它的实现部分分离,是它们都可以独立地变化。它很好的支持了开闭原则和组合锯和复用原则。实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。

3.组合模式 Composite
  组合模式将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

4.装饰模式 Decorator
  装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。 装饰模式没有通过继承原有类来扩展功能,但却达到了一样的目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。

5.外观模式 Facade
   外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
  外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。

6.享元模式 Flyweight
   享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。.
   享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。

7.代理模式 Proxy   
  为其他对象提供一种代理,并由代理对象控制对原对象的引用,以间接控制对原对象的访问。

结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与...

结构模式之间有许多相似之处,因为在对象模型结构中存在几种关系:类之间的继承和实现,加上对象组合,这些是PHP设计模式的主要目的。

代码分析
interface Implementor{

  void operationImpl();
}

abstract class Abstraction{
  protected Implementor implementor;

  public Abstraction(Implementor implementor){
    this.implementor = implementor;
  }

  public void operation(){
    implementor.operationImpl();
  }
}

class ConcreteImplementorA implements Implementor {
  @Override
  public void operationImpl() {
    System.out.println("具体实现A");
  }  
}

class ConcreteImplementorB implements Implementor {
  @Override
  public void operationImpl() {
    System.out.println("具体实现B");
  }  
}

class RefinedAbstraction extends Abstraction{

  public RefinedAbstraction(Implementor implementor) {
    super(implementor);
  }

  public void otherOperation(){
    System.out.println("其他操作");
  }
}

public class MainTest {

  public static void main(String arg[]) {
    Implementor implementor = new ConcreteImplementorA();
    RefinedAbstraction abstraction = new RefinedAbstraction(implementor);
    abstraction.operation();
    abstraction.otherOperation();
  }
}

这三个模式维护相同的对象接口,它们透明地添加正交关注,客户端不会察觉: ◆复合模式为其它对象增加容器组织层次结构,并将树作为其它树的叶子进行重用; ◆装饰模式通过拦截方法授权添加行为,避免引入大量的子类; ◆代理模式给一个还不存在或很难访问的对象授权操作。

扩展

几种常用的代理模式

  1. 图片代理

一个很常见的代理模式的应用实例就是对大图浏览的控制。

用户通过浏览器访问网页时先不加载真实的大图,而是通过代理对象的方法来进行处理,在代理对象的方法中,先使用一个线程向客户端浏览器加载一个小图片,然后在后台使用另一个线程来调用大图片的加载方法将大图片加载到客户端。当需要浏览大图片时,再将大图片在新网页中显示。如果用户在浏览大图时加载工作还没有完成,可以再启动一个线程来显示相应的提示信息。通过代理技术结合多线程编程将真实图片的加载放到后台来操作,不影响前台图片的浏览。

  1. 远程代理:远程代理可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的远程业务对象是局域的而不是远程的,而远程代理对象承担了大部分的网络通信工作。

  2. 虚拟代理:当一个对象的加载十分耗费资源的时候,虚拟代理的优势就非常明显地体现出来了。虚拟代理模式是一种内存节省技术,那些占用大量内存或处理复杂的对象将推迟到使用它的时候才创建。

  3. 动态代理

较为高级的代理模式,它的典型应用就是Spring AOP。

复合-装饰-代理(Composite-Decorator-Proxy)

模式定义

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式。

对象组合的最大优势在于可以在运行时基于配置建立起一个关系,并不用修改实际的代码,它是类继承和接口实现需要的一个操作。实际上,你完全可以通过修改对象之间而非类之间的链接定义一个应用程序的功能,这是设计的一部分。结构模式清单

模式结构

装饰模式包含如下角色:

Component: 抽象构件
ConcreteComponent: 具体构件
Decorator: 抽象装饰类
ConcreteDecorator: 具体装饰类

计算机编程 1

Paste_Image.png

这三个模式的目标是竞争耦合: ◆适配器模式使用不同的接口连接对象; ◆桥接模式将一个M抽象层和一个N实现层分离成N M类,代替M*N用法; ◆外观模式创建一个新的统一的界面来访问子系统。

代码分析
int main()
{
    Facade fa;
    fa.wrapOpration();
    return 0;
}
class Facade
{

public:
    Facade();
    virtual ~Facade();
    void wrapOpration();
private:
    SystemC *m_SystemC;
    SystemA *m_SystemA;
    SystemB *m_SystemB;
};

Facade::Facade(){
    m_SystemA  = new SystemA();
    m_SystemB = new SystemB();
    m_SystemC = new SystemC();
}

void Facade::wrapOpration(){
    m_SystemA->operationA();
    m_SystemB->operationB();
    m_SystemC->opeartionC();
}

最后,享元模式是一个无身份的ValueObjects标准实现。

扩展
  1. 一个系统有多个外观类
    在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。

  2. 不要通过继承一个外观类在子系统中加入新的行为
    外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。

  3. 外观模式与迪米特法则(最少知道原则)
    外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。

  4. 抽象外观类的引入
    外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时可以通过修改配置文件来达到不修改源代码并更换外观类的目的。

  • 适配器模式(Adapter)
    重要程度:4

  • 桥接模式(Bridge)
    重要程度:3

  • 组合模式(Composite)
    重要程度:4

  • 装饰模式(Decorator)
    重要程度:3

  • 外观模式(Facade)
    重要程度:5

  • 享元模式(Flyweight)
    重要程度:1

  • 代理模式(Proxy)
    重要程度:4

六、享元模式(Flyweight)

优点

对客户屏蔽子系统组件,实现了子系统与客户之间的松耦合关系

缺点

享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。

优点

可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。

模式结构

计算机编程 2

Paste_Image.png

模式定义

对象的多次复用

五、外观模式(Facade)

代码分析
public abstract class Company {  
    private String name;  

    public Company(String name) {  
        this.name = name;  
    }  

    public Company() {  
    }  

    protected abstract void add(Company company);  

    protected abstract void remove(Company company);  

    protected abstract void display(int depth);  
}  

public class ConcreteCompany extends Company {  
    private List<Company> cList;  

    public ConcreteCompany() {  
        cList = new ArrayList<Company>();  
    }  

    public ConcreteCompany(String name) {  
        super(name);   
        cList = new ArrayList<Company>() ;   
    }  

    @Override  
    protected void add(Company company) {  
        cList.add(company);  
    }  

    @Override  
    protected void display(int depth) {  

        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i  ) {  
            sb.append("-");   
        }  
        System.out.println(new String(sb)   this.getName());  
        for (Company c : cList) {  
            c.display(depth   2);  
        }  
    }  

    @Override  
    protected void remove(Company company) {  
        cList.remove(company);  
    }  
}  

public class FinanceDepartment extends Company {  


    public FinanceDepartment(){  

    }  

    public FinanceDepartment(String name){  
        super(name);  
    }  

    @Override  
    protected void add(Company company) {  

    }  

    @Override  
    protected void display(int depth) {  
        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i  ) {  
            sb.append("-");  
        }  
        System.out.println(new String(sb)   this.getName() ) ;   
    }  

    @Override  
    protected void remove(Company company) {  

    }  

}  

public class HRDepartment extends Company {  


    public HRDepartment(){  

    }  

    public HRDepartment(String name){  
        super(name);  
    }  

    @Override  
    protected void add(Company company) {  

    }  

    @Override  
    protected void display(int depth) {  
        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i  ) {  
            sb.append("-");   
        }  
        System.out.println(new String(sb)   this.getName() ) ;   
    }  

    @Override  
    protected void remove(Company company) {  

    }  

}  


public class Client {  


    public static void main(String[] args) {  

        Company root = new ConcreteCompany();  
        root.setName("北京总公司");  
        root.add(new HRDepartment("总公司人力资源部"));  
        root.add(new FinanceDepartment("总公司财务部"));  
        Company shandongCom = new ConcreteCompany("山东分公司");  
        shandongCom.add(new HRDepartment("山东分公司人力资源部"));  
        shandongCom.add(new FinanceDepartment("山东分公司账务部"));  

        Company jinanCom = new ConcreteCompany("济南办事处");  
        jinanCom.add(new FinanceDepartment("济南办事处财务部"));  
        jinanCom.add(new HRDepartment("济南办事处人力资源部"));   
        shandongCom.add(jinanCom);  

        root.add(shandongCom);  
        root.display(0);  
    }  

}  

类似于树

一、适配器模式(Adapter)

模式结构

适配器模式包含如下角色:

Target:目标抽象类
Adapter:适配器类
Adaptee:适配者类
Client:客户类

适配器模式有对象适配器和类适配器两种实现:

  1. 类适配器:
![](https://upload-images.jianshu.io/upload_images/3167794-689372a6a6e8c92f.jpg)

类适配器



类适配器,Adapter 类既继承了 Adaptee (被适配类),也实现了 Target
接口
  1. 对象适配器:
![](https://upload-images.jianshu.io/upload_images/3167794-d64ed7ba18e04a34.png)

对象适配器



对象适配器,它不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式。

从类图中我们也可以看到 对象适配器比起类适配器 需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。

优点

将目标类和适配者类解耦,增加了类的透明性和复用性,灵活性和扩展性都非常好,完全符合“开闭原则”。

  • 类结构型模式关心类的组合,一般只存在继承关系和实现关系

  • 对象结构型模式关心类与对象的组合,一般关系为关联关系。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分类结构型模式都是对象结构型模式。

缺点

在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类的源代码,违背了“开闭原则”。

来源:《图说设计模式》

缺点

类适配器一次最多只能适配一个适配者类,使用有一定的局限性。(不能多继承)

而对象适配器虽然可以把适配者类和它的子类都适配到目标接口,但是更改适配者的方法十分麻烦,既需要更改适配器,也需要更改适配者

七、代理模式(Proxy)

模式结构

桥接模式包含如下角色:

Abstraction:抽象类
RefinedAbstraction:扩充抽象类
Implementor:实现类接口
ConcreteImplementor:具体实现类

计算机编程 3

Paste_Image.png

扩展
  • 桥接模式和适配器模式的区别

很多时候经常容易把桥接模式和适配器模式弄混。那什么时候用桥接,什么时候用适配器呢 ?

共同点:

桥接和适配器都是让两个东西配合工作

不同点:

适配器:改变已有的两个接口,让他们相容。

桥接模式:分离抽象化和实现,使两者的接口可以不同,目的是分离。

所以说,如果你拿到两个已有模块,想让他们同时工作,那么你使用的适配器。 如果你还什么都没有,但是想分开实现,那么桥接是一个选择。

桥接是先有桥,才有两端的东西 适配是先有两边的东西,才有适配器 。

桥模式并不同于适配器模式,适配器模式其实是一个事后诸葛亮,当发现以前的东西不适用了才去做一个弥补的措施。桥模式相对来说所做的改变比适配器模式早,它可以适用于有两个甚至两个以上维度的变化。

桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

模式动机

适配器可以使由于接口不兼容而不能交互的类可以一起工作。类似于电源适配器的设计。

四、装饰模式(Decorator)

模式动机

将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对耽搁对象和组合对象的使用具有一致性。

结构型模式(Structural Pattern)描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过 简单积木的组合形成复杂的、功能更为强大的结构。

模式分析

据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。

外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。

外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。

扩展

当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求,它适用于一个接口不想使用其所有的方法的情况。因此也称为单接口适配器模式。

模式定义

装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),它是一种对象结构型模式。

模式结构

代理模式包含如下角色:

计算机编程,Subject: 抽象主题角色
Proxy: 代理主题角色
RealSubject: 真实主题角色

计算机编程 4

Paste_Image.png

模式动机

在某些情况下,客户不想或者不能直接引用一个对 象,此时可以通过一个称之为“代理”的第三者来实现 间接引用。代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务。

应用

Java 的I/O API就是使用装饰模式实现的

三、组合模式(Composite)

代码分析

典型的类适配器代码

// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
    public void specificRequest() {
        System.out.println("被适配类具有 特殊功能...");
    }
}
// 目标接口,或称为标准接口
interface Target {
    public void request();
}

// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
    public void request() {
        System.out.println("普通类 具有 普通功能...");
    }
}

// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
    public void request() {
        super.specificRequest();
    }
}

典型的对象适配器代码

// 适配器类,直接关联被适配类,同时实现标准接口
class Adapter implements Target{
    // 直接关联被适配类
    private Adaptee adaptee;

    // 可以通过构造函数传入具体需要适配的被适配类对象
    public Adapter (Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void request() {
        // 这里是使用委托的方式完成特殊功能
        this.adaptee.specificRequest();
    }
}

两种方式的区别 :

  • 对象适配器模式可以直接使用一个已有的Adaptee的实例来转换接口。
  • 类适配器继承了Adaptee,所以可以通过覆写来扩展SpecificRequest()
  • 类适配器模式因为是继承所以相对静态,而对象适配器模式是包含是组合相对灵活(可以通过写adaptee子类扩展功能)
模式结构

外观模式包含如下角色:

Facade: 外观角色
SubSystem:子系统角色

计算机编程 5

Paste_Image.png

二、桥接模式(Bridge)

应用

享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。

应用

JDBC驱动软件就是一个介于JDBC接口和数据库引擎接口之间的适配器软件。

模式动机

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:

第一种设计方案是为每一种形状都提供一套各种颜色的版本。
第二种设计方案是根据实际需要对形状和颜色进行组合
对于有两个变化维度的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

包含模式

模式动机

一般有两种方式可以实现给一个类或对象增加行为:

  1. 继承机制
  2. 关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)

装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。

结构型模式可以分为类结构型模式和对象结构型模式:

代码分析

现在需要一个汉堡,主体是鸡腿堡,可以选择添加生菜、酱、辣椒等等许多其他的配料,这种情况下就可以使用装饰者模式。

//汉堡基类(被装饰者)
public abstract class Humburger {    

    protected  String name ;    

    public String getName(){    
        return name;    
    }    

    public abstract double getPrice();    

}    
//鸡腿堡类(被装饰者的初始状态,有些自己的简单装饰)
public class ChickenBurger extends Humburger {    

    public ChickenBurger(){    
        name = "鸡腿堡";    
    }    

    @Override    
    public double getPrice() {    
        return 10;    
    }    
}
//配料的基类(装饰者,用来对汉堡进行多层装饰,每层装饰增加一些配料)
public abstract class Condiment extends Humburger {    

    public abstract String getName();    

}    
//生菜(装饰者的第一层)
 public class Lettuce extends Condiment {    

    Humburger humburger;    

    public Lettuce(Humburger humburger){    
        this.humburger = humburger;    
    }    

    @Override    
    public String getName() {    
        return humburger.getName() " 加生菜";    
    }    

    @Override    
    public double getPrice() {    
        return humburger.getPrice() 1.5;    
    }    

}    
//辣椒(装饰者的第二层)
public class Chilli extends Condiment {    

    Humburger humburger;    

    public Chilli(Humburger humburger){    
        this.humburger = humburger;    

    }    

    @Override    
    public String getName() {    
        return humburger.getName() " 加辣椒";    
    }    

    @Override    
    public double getPrice() {    
        return humburger.getPrice();  //辣椒是免费的哦    
    }    

}    
//测试类
public static void main(String[] args) {    
        Humburger humburger = new ChickenBurger();    
        System.out.println(humburger.getName() "  价钱:" humburger.getPrice());    
        Lettuce lettuce = new Lettuce(humburger);    
        System.out.println(lettuce.getName() "  价钱:" lettuce.getPrice());    
        Chilli chilli = new Chilli(humburger);    
        System.out.println(chilli.getName() "  价钱:" chilli.getPrice());    
        Chilli chilli2 = new Chilli(lettuce);    
        System.out.println(chilli2.getName() "  价钱:" chilli2.getPrice());    
    }      
模式结构

享元模式包含如下角色:

Flyweight: 抽象享元类
ConcreteFlyweight: 具体享元类
UnsharedConcreteFlyweight: 非共享具体享元类
FlyweightFactory: 享元工厂类

计算机编程 6

Paste_Image.png

模式定义

给某一个对象提供一个代 理,并由代理对象控制对原对象的引用。它是一种对象结构型模式。

TAG标签:
版权声明:本文由澳门新葡8455手机版发布于计算机编程,转载请注明出处:Java的结构型情势计算机编程,设计格局