`

3大结构模式辨析

    博客分类:
  • java
阅读更多

首先看看维基百科中对7个结构模式的定义 from Wikipedia, the free encyclopedia

 

Structural patterns
Adapter 适配
allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.

Bridge 桥梁
decouples an abstraction from its implementation so that the two can vary independently.

Composite
composes zero-or-more similar objects so that they can be manipulated as one object.

Decorator 装饰
dynamically adds/overrides behaviour in an existing method of an object.

Facade
provides a simplified interface to a large body of code.

Flyweight
reduces the cost of creating and manipulating a large number of similar objects.

Proxy 代理
provides a placeholder for another object to control access, reduce cost, and reduce complexity.

 

合成,门户和享元相对独立,比较好分辨。

 

这里仅仅对适配,装饰和代理进行辨析。

 

适配的目的是匹配两个不同的接口。

装饰的目的是增强接口的实现。

代理的目的是有代理对象控制原对象,不改变接口。

 

这里给出例子

 

假设有饭店和咖啡厅两个接口。我们希望实现了咖啡厅的类,可以去做饭店的事情,就是适配,增强咖啡厅自身功能就是装饰,对咖啡连锁供应商的调度就是代理。

 

 

package mars.designpattern.info;

public interface 饭店 {

    void 提供饭菜();
   
    void 提供啤酒();
}

 

package mars.designpattern.info;

public interface 咖啡厅 {

    void 提供西点();

    void 提供咖啡();

    void 提供音乐();

    void 提供上网();
}

 

package mars.designpattern.structural;

import mars.designpattern.info.咖啡厅;
import mars.designpattern.info.饭店;
import mars.designpattern.info.impl.星巴克;

public class 适配 implements 饭店 {
    private 咖啡厅 中关村店 = new 星巴克();

    @Override
    public void 提供饭菜() {
        中关村店.提供西点();
        中关村店.提供咖啡();
    }

    @Override
    public void 提供啤酒() {
        // 这个真没有
    }
}

 

package mars.designpattern.structural;

import java.util.Queue;

import mars.designpattern.info.咖啡厅;

public class 装饰 implements 咖啡厅 {

    private 咖啡厅 基础店 = new 星巴克();
    
    private void 提供苹果笔记本() {
        System.out.println("苹果笔记本 2小时内免费租用");
    }

    private void 咖啡杯服务() {
        System.out.println("根据会员资料,免费提供一个12星座咖啡杯,并免费帮助寄存");

    }
   
    private void 点播服务(){
        System.out.println("提供有偿点播服务");
    }
   
    private Queue 订餐;
    public void 订餐(){
        System.out.println("提供订餐电话");  
        订餐.add("订餐信息");
    }
   
    private void 提供外卖(){
        System.out.println("根据订餐信息 免费送货");
    }

    @Override
    public void 提供上网() {
            基础店.提供上网();
        提供苹果笔记本();
        System.out.println("无线宽带");

    }

    @Override
    public void 提供咖啡() {
        基础店.提供咖啡();
        System.out.println("手工研磨");
        咖啡杯服务();
       
        if(订餐.remove("订餐信息")){
            提供外卖();
        }
    }

    @Override
    public void 提供西点() {
            基础店.提供西点();
    }

    @Override
    public void 提供音乐() {
        基础店.提供音乐();
        点播服务();
    }
}

 

package mars.designpattern.structural;

import mars.designpattern.info.咖啡厅;
import mars.designpattern.info.impl.星巴克;

public class 代理 implements 咖啡厅 {
    星巴克 星巴克注册者;
   
    private void 记账(){
       
    }
   
    @Override
    public void 提供上网() {
        星巴克注册者.提供上网();
    }

    @Override
    public void 提供咖啡() {
        星巴克注册者.提供咖啡();
        记账();
    }

    @Override
    public void 提供西点() {
        星巴克注册者.提供西点();
        记账();
    }

    @Override
    public void 提供音乐() {
        星巴克注册者.提供音乐();
    }
}

 

分享到:
评论
6 楼 marshan 2010-05-06  
mococa 写道
装饰的例子讲得不太好,有装饰者但没有被装饰者


有道理。我偷懒了。增加了"基础店"。谢谢。
5 楼 mococa 2010-05-05  
装饰的例子讲得不太好,有装饰者但没有被装饰者
4 楼 lxs647 2010-05-05  
hellojinjie 写道
问下,你们在真实的开发中有用过中文的变量名和方法名吗,,

有时候经常为一个变量的命名头痛半天。


楼主这个仅仅只是举的一个例子,是为了方便理解、、、
实际应用当中是不可能用中文来做变量名的、、、
否则会出现很多莫名其妙的问题、、、
3 楼 hellojinjie 2010-05-05  
问下,你们在真实的开发中有用过中文的变量名和方法名吗,,

有时候经常为一个变量的命名头痛半天。
2 楼 prowl 2010-05-05  
例子很生动,支持一个。
1 楼 jadewoo 2010-05-05  
楼主举的例子很生动,我看了后,使设计模式迷惑了很久的我有个大概的理解!顶了

相关推荐

Global site tag (gtag.js) - Google Analytics