美高梅网址注册-澳门mgm4858集团登录网址
做最好的网站
来自 澳门mgm4858集团登录网址 2019-10-06 06:01 的文章
当前位置: 美高梅网址注册 > 澳门mgm4858集团登录网址 > 正文

对抽象装饰者的抽象部分进行实现,也是继承关

装饰者模式又叫包装模式,他能够以透明的方式扩展对象的功能,是继承方式的另外一种替代方案。和代理模式很相似,但在对被装饰的对象的控制程度是不同的;装饰者模式是对对象功能的加强,而代理模式是对对象施加控制,并不提供对对象本身功能的加强。

图片 1

介绍

装饰模式(Decorator Pattern) 也称为包装模式(Wrapper Pattern),结构型设计模式之一,其使用一种对客户端透明的方式来动态地扩展对象的功能,同时它也是继承关系的一种代替方案之一。

首先看下装饰者模式的类图

简述

装饰者模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),以透明动态的方式来动态扩展对象的功能,也是继承关系的一种代替方案。

图片 2装饰模式.png

  • Component:抽象组件(可以是抽象类或者接口),被装饰的原始对象
  • ConcreteComponent:具体实现类,被装饰的具体对象
  • Decorator:抽象装饰者,职责就是为了装饰我们的组件对象,内部一定要有一个指向组件对象的引用
  • ConcreteDecoratorA:装饰者具体实现类,只对抽象装饰者做出具体实现
  • ConcreteDecoratorB:同上

定义

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。

图片 3

举个栗子

人定义为抽象类,有一个抽象方法eat()

public abstract class Person { public abstract void eat();}

接着创建一个NormalPerson类继承Person,对eat()方法有了具体实现;NormalPerson类就是我们需要装饰的对象。

public class NormalPerson extends Person { @Override public void eat() { System.out.println; }}

这里定义一个PersonFood类来表示装饰者的抽象类,保持了一个对Person的引用,可以方便调用具体被装饰的对象方法,这样就可以方便的对其进行扩展功能,并且不改变原类的层次结构。

public class PersonFood extends Person { private Person person; public PersonFood(Person person){ this.person = person; } @Override public void eat() { person.eat(); }}

接着就是具体的装饰类了,这两个类没有本质上的区别,都是为了扩展NormalPerson类,不修改原有类的方法和结构

public class ExpensiveFood extends PersonFood { public ExpensiveFood(Person person) { super; } @Override public void eat() { super.eat(); eatSteak(); drinkRedWine(); } public void eatSteak(){ System.out.println; } public void drinkRedWine(){ System.out.println; }}public class CheapFood extends PersonFood { public CheapFood(Person person) { super; } @Override public void eat() { super.eat(); eatNoodles(); } public void eatNoodles(){ System.out.println; }}

客户端代码

public class Client { public static void main(String[] args){ Person person = new NormalPerson(); PersonFood cheapFood = new CheapFood; cheapFood.eat(); PersonFood expensiveFood = new ExpensiveFood; expensiveFood.eat(); }}

使用场景

需要透明且动态地扩展类的功能时

说明下:Component,给出一个抽象接口,规范实现类的一些方法;ConcreteComponent:具体的一个组件,实现了接口方法;Decorator:抽象的装饰者,对接口的一个引用,在 method 方法里面使用这个引用完成任务;(代理模式需要实例化)ConcreteDecorator:具体的装饰者,对抽象装饰者的抽象部分进行实现

android中的装饰者模式

android中,Context就是典型的装饰者模式Context是抽象类,真实的功能实现实在ComtextImpl中完成,ComtextImpl就是Context的实现类;然后看源码会发现Activity是继承于ContextThemeWrapper而不是直接继承于Context。其中ContextThemeWrapper 继承于ContextWrapper,而ContextWrapper继承于Context。这里就可以看出来一点装饰者模式了,其中装饰者所调用的方法就是startActivity方法,在ContextWrapper中会发现startActivity方法调用了ComtextImpl中对应的方法,实质上ContextWrapper中所有方法都仅仅是调用了ComtextImpl中的方法,这就和装饰者模式基本就对应上了。

角色介绍

  • Component 抽象组件,可以是一个接口或者抽象类,其充当的就是被装饰的原始对象
  • ConcreteComponent 组件具体实现类,也是我们装饰的具体对象
  • Decorator 抽象装饰者,其承担的职责就是为了装饰我们的组件对象,其内部一定要有一个指向组件对象的引用。大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类。当然,如果装饰逻辑单一,只有一个的情况我们可以省略该类直接作为具体的装饰者。
  • ConcreteDecorator 装饰者具体实现类,只是对抽象装饰者做出具体实现。
  • Client 客户类,创建组件实现类的对象,根据组件对象构造装饰者对象,调用装饰者对象的方法执行任务

抽象的装饰者中持有一个组件实现类的对象的引用,并且抽象的装饰者要继承抽象的组件。在抽象装饰者对组件抽象方法的实现过程中,调用组件实现类的引用的对应方法。在装饰者的实现类中,重写从父类继承的抽象组件的方法,在 super.operate() 前后可以添加需要插入的装饰代码。

抽象装饰者中保持对组件类对象的引用,可以方便地调用具体被装饰对象中的方法,我们就可以在不破坏原类层次结构的情况下为类增加一些功能,我们只需要在被装饰对象的想应方法前或后添加相应逻辑即可。

下面给出实现代码抽象组件接口:

优点

  • 装饰者模式与继承关系的目的都是要扩展对象的功能,但是装饰者模式可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

Android 源码中的装饰模式

Context 在 Android 中被称为“上帝对象”,它是一个抽象类,对应的有 ContextWrapper,ContextImpl,Activity,Service,Application

Context 对应抽象模式中的抽象组件,ContextImpl 继承了 Context,对应装饰模式中的组件实现类。

ContextWrapper 继承了 Context,对应装饰模式中的装饰类对象,其保持了一个对 ContextImpl 的引用。

Activity、Service,Application 继承了 ContextWrapper ,对应装模式中的具体装饰者

public interface Component { public void method();}

缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

装饰模式和代理模式区别

  1. 装饰模式和我们前面的代理模式有点类似,有时容易混淆,经常将装饰模式看作代理。

  2. 装饰模式是对客户端透明的方式扩展对象的功能,是继承的一个代替方案

  3. 而代理模式则是给对象提供一个代理,并有代理对象来控制对原有对象的引用

  4. 装饰模式应该为所装饰的对象增强功能

  5. 代理模式是对代理的对象施加控制,但不对对象本身功能进行增强

具体组件的实现代码:

与代理模式的区别

其实装饰者模式和代理模式很像,但是两者的目的不尽相同。装饰者模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;而代理模式则是一个给对象提供一个代理对象,并由代理对象来控制对原有对象的引用。

装饰者模式为本装饰的对象进行功能扩展;代理模式对代理对象进行控制,但不做功能扩展

本文由美高梅网址注册发布于澳门mgm4858集团登录网址,转载请注明出处:对抽象装饰者的抽象部分进行实现,也是继承关

关键词: