【设计模式】设计模式真的懂得这些就够了,来来来,从代理模式&装饰器模式讲起......

设计模式分为三种:
1. 创建型
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
2. 结构型
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
3. 行为型
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

本篇Colin带你从『结构型』设计模式中的『代理模式』和『装饰器模式』。

一. 代理模式

1. 从UML图中理解『代理模式』中类的结构关系

这里写图片描述
代理模式的类结构非常简单,其主要成员有一个接口、一个实现了该接口的实现类、一个代理类。代理模式的定义是,给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。顾名思义,代理模式就是提供了一个中介,来为原对象完成某项任务。


举个栗子:携程app的图片加载框架有两种,一种是universalImageLoader,一种是fresco,那么业务部门要想使用图片加载器时,他们是直接调用universalImageLoader/fresco的接口吗?如果是这样,那哪天框架组宣布停用其中一种图片加载框架,或是新增Glide图片加载框架时,业务部门的代码是不是就要重新全部重新写?这个时候就可以使用代理模式提供一个中介,中介可以控制使用哪种图片加载框架,业务部门也只是调用中介提供的方法,而不用管具体实现是哪种图片加载框架。

2. 为什么要用『代理模式』?

  • 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
  • 开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

3. 一言不合上代码

一个接口

 public interface ImageLoader {
     void display();
 }

一个接口实现类

 public class FrescoImageLoader implements ImageLoader { 
     @Override
     public void display() {
         System.out.println("fresco加载图片");
     }
 }

一个代理

public class ImageLoaderHelper implements ImageLoader {
     private ImageLoader imageLoader; 
     public ImageLoaderHelper(final ImageLoader imageLoader) {
         this.imageLoader = imageLoader;
     }
     @Override
     public void display() {
         imageLoader.display();
     }
 }

二. 装饰模式

1. 从UML图中理解『装饰模式』中类的结构关系

这里写图片描述
装饰模式的类结构也非常简单,包括一个接口、一个接口的实现类、一个抽象装饰类、多个具体装饰类。装饰模式的定义是,动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比「子类继承父类」实现更为灵活。


举个栗子:我们喝一杯咖啡,可以加奶、加糖、加冰块。有的人喜欢喝加糖的咖啡,有的人喜欢喝加奶的咖啡,还有的人喜欢喝加冰块的咖啡。当然,我们也可以采用继承的方式喝到我们想喝的咖啡,不过接下来我们看看采用组合的方式如何实现。

2. 为什么要用『装饰模式』?

  • 装饰类和被装饰类可以独立发展,不会相互耦合
  • 动态的将责任附加到对象身上。

3. 一言不合上代码

一个接口

public interface Drink {
    public void taste();
}

一个接口实现类

public class Coffee implements Drink {
    public float taste() {
        System.out.println("咖啡好苦,好提神");
    }
}

一个抽象装饰类

public abstract class Decorator implements Drink {
    protected Drink decorator;

    public CondimentDecorator(Drink decorator) {
        this.decorator = decorator;
    }

    public void taste() {
        decorator.taste()
    }
}

加糖

public class Sugar extends Decorator {
    public Sugar(Drink decorator) {
        super(decorator);
    }

    @Override
    public void taste() {
        System.out.println("加了糖,味道甜多了");
    }
}

加奶

public class Milk extends Decorator {
    public Milk(Drink decorator) {
        super(decorator);
    }

    @Override
    public void taste() {
        System.out.println("加了奶,味道绵绸多了");
    }
}

加冰

public class Ice extends Decorator {
    public Ice(Drink decorator) {
        super(decorator);
    }

    @Override
    public void taste() {
        System.out.println("加了冰,好凉爽");
    }
}

三. 装饰模式和代理模式不是一样吗??

代理模式和装饰模式非常类似,甚至代码都类似。二者最主要的区别是:代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行,主要是隔离了真正实现。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已。

猜你喜欢

转载自blog.csdn.net/colinandroid/article/details/80490144