设计模式学习之路-装饰者模式(附设计原则)

原创 2016年08月29日 17:09:43

设计模式,学过了简单工厂和策略模式,简单实用,在设计代码的时候,经常使用就会养成一个好的代码习惯,时时刻刻保持代码的可维护性,可复用性,灵活性,可扩展性。这些是写出优美代码的前提。那么接下来,一起学习一些设计原则。

第一个设计原则:

单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因。白话呢,就是一个类,职责作用尽可能的单一,这样就可以降低耦合性,提高代码的可维护性,灵活性。

还是拿计算器的业务逻辑举例子,把运算类抽象出来,然后每子类是一种运算,这样想要在添加一种运算,亦或是修改某个运算的逻辑。都会很方便,不会影响到别的代码逻辑。这就是单一原则的运用。

第二个设计原则:

开放-封闭原则(ASD),是说软件实体应该可以扩展,但是不可修改。还是计算器业务逻辑,将运算父类抽象出来,封装之后,可以对运算父类进行扩展而不去修改父类的源码,这就是开放封闭原则。在对一个类封装时,要考虑到这个类的可扩展性,同时也要保护已有代码不被修改。

第三个设计原则:

依赖倒置原则,高层模块不应该依赖低层模块,两个模块都应该依赖抽象,抽象不应该依赖细节,而细节应该依赖抽象。就是经常说的面向接口(抽象)编程,在没有面对对象编程思想时,编程逻辑就是把所有低层模块(函数)封装起来,在构建高层模块时,就直接调用封装好的低层模块,这样就会造成高层模块依赖低层模块,耦合性太高,一旦需求改变,就要从低层模块开始修改,那么高层模块也会随之改变。那么代码的灵活性,可复用性,可扩展性,维护性都太低了。但是使用依赖倒置原则就会很好避免这个问题。

第四个设计原则:

里氏代换原则(LSP),子类型必须能够替换掉它们的父类型。也就是子类的对象可以完全当成父类的对象来使用。软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。代码的可扩展性就是基于这个设计原则之上。

第五个设计原则:

迪米特法则(LoD):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法,可以通过第三者转发这个调用。

接下来看看装饰者模式的UML图:


Component是定义一个对象接口,可以给这些对象动态的添加职责。ConcreteComponnet是定义了一个具体的对象,也可以给这个对象添加一些职责,Decortor装饰抽象类,从外类扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的,至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。

基本实现代码:

abstract class Component{
  public abstract void Operation();
}
class ConcreteComponent extends Compennet{
 @Override
 public void Operation(){
  //具体对象的操作
 }
}
abstract class Decorator extends Component{
 protected Component component;
 public void setComponent(Component component){
  this.component = component;
 }
 @Override
 public void Operation(){
  if(component != null){
    component.Operation();
  }
 }
}
class ConcreteDecoratorA extends Decorator{
 private String addState;
 @Override
 public void Operation(){
  super.Operation();
  addState = "new State";
  //具体装饰对象A的操作
 }
}
这些是按照UML设计的基本模式,以后可以直接照着这个模式写。
依然举个例子来学习这个设计模式,装饰者就像穿衣服一样,那么以人穿衣服为例子。

先创建一个接口,穿衣服是为了展示,写一个show方法。

package com.abings.componentmodel.Component;

/**
 * Created by Shuwen on 2016/8/30.
 */
public interface Component {
    void show();
}
在创建一个ConcreteComponent,作为创建装饰者对象,也就是人。

package com.abings.componentmodel.Component;

import android.content.Context;
import android.widget.Toast;

/**
 * Created by Shuwen on 2016/8/30.
 */
public class ConcreteComponent implements Component {

    private Context context;
    public ConcreteComponent(Context context){
        this.context = context;
    }

    @Override
    public void show() {
        Toast.makeText(context, "装扮的美女", Toast.LENGTH_SHORT).show();
    }
}
创建一个Decorator,抽象装饰类。也就是衣服抽象类。

package com.abings.componentmodel.Component;

/**
 * Created by Shuwen on 2016/8/30.
 */
public abstract class Decorator implements Component{

    private Component component;

    public void setComponent(Component component){
        this.component = component;
    }

    @Override
    public void show() {
        if (component != null){
            component.show();
        }
    }
}
继承Decorator,创建各种衣服,这里按照单一原则创建类。利于维护和扩展。

package com.abings.componentmodel.Component;

import android.content.Context;
import android.widget.Toast;

/**
 * Created by Shuwen on 2016/8/30.
 */
public class ConcreteDecoratorA extends Decorator {
    private Context context;
    public ConcreteDecoratorA(Context context){
        this.context = context;
    }


    @Override
    public void show() {
        Toast.makeText(context, "穿内衣", Toast.LENGTH_SHORT).show();
        super.show();
    }
}
package com.abings.componentmodel.Component;

import android.content.Context;
import android.widget.Toast;

/**
 * Created by Shuwen on 2016/8/30.
 */
public class ConcreteDecoratorB extends Decorator {

    private Context context;
    public ConcreteDecoratorB(Context context){
        this.context = context;
    }

    @Override
    public void show() {
        Toast.makeText(context, "穿外套", Toast.LENGTH_SHORT).show();
        super.show();
    }
}
客户端

package com.abings.componentmodel;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.abings.componentmodel.Component.ConcreteComponent;
import com.abings.componentmodel.Component.ConcreteDecoratorA;
import com.abings.componentmodel.Component.ConcreteDecoratorB;
import com.abings.componentmodel.Component.ConcreteDecoratorC;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ConcreteComponent concreteComponent = new ConcreteComponent(this);
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(this);
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(this);
        ConcreteDecoratorC concreteDecoratorC = new ConcreteDecoratorC(this);

        //穿衣服的过程,依次对对象进行扩展,装扮
        concreteDecoratorA.setComponent(concreteComponent);
        concreteDecoratorB.setComponent(concreteDecoratorA);
        concreteDecoratorC.setComponent(concreteDecoratorB);
        concreteDecoratorC.show();

    }
}
这就是装饰者模式,这个模式优点在于,对已有对象进行额外扩展,而且扩展的内容和方式都是不可见,隐蔽的。例子的代码很简单,附上git:

https://github.com/SingleShu/ComponentModel










版权声明:【码字不易,转载请标明出处,http://blog.csdn.net/sw5131899的博客,欢迎转载】

设计模式 装饰者模式 带你重回传奇世界

今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。 装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。 先简单描述下装饰者模式发挥作用的地方,当我...
  • lmj623565791
  • lmj623565791
  • 2014年04月21日 20:21
  • 17620

我所理解的设计模式(C++实现)——装饰者模式(Decorator Pattern)

解决的问题: 我们在装饰新家的时候买了几幅抽象画,买回来之后发现有些加上色彩艳丽的边框更适合我们,而有的加上玻璃罩之后更能符合我们的使用。那我们来怎么解决这个问题呢?他需要动态的给别的对象增加额...
  • tanningzhong
  • tanningzhong
  • 2015年01月24日 14:47
  • 570

架构师学习之路1设计模式

想学习基础在数据结构和设计模式之间犹豫了很久,最后还是决定先看一下常用的设计模式 参考书:Design Pattern-Head First 中文版 原则 封装变化 多用组合,少用继承 针对接口编程,...
  • zsr251
  • zsr251
  • 2015年06月30日 13:38
  • 408

Java:一夜一发设计模式(一)------装饰者模式

一,什么时候使用装饰者模式?比如有一家店卖饮品,饮品就有不少种,每一种还可以加项,比如给可乐加冰,加糖,兑水什么的,每次加项的价格还不同,就会将代码弄的很繁琐,这种情况下就可以使用装饰者模式来实现. ...
  • android_zyf
  • android_zyf
  • 2017年03月30日 01:53
  • 585

设计模式的学习之路 --- 第一站(模板模式)

前言: 作为设计模式里面最简单的设计模式之一,却被广泛使用的。作为学习设计模式的开篇真=真是再适合不过了。 这个设计模式之中仅仅使用了继承关系。虽然Java里面因为单继承、多实现的原因不建议过多的...
  • qq_27232757
  • qq_27232757
  • 2017年09月14日 15:01
  • 61

Java 设计模式 装饰者模式

装饰者模式 在设计的时候,往往要给一个对象的功能进行一些修饰,对功能进行拓展和增强,以满足我们的需求。    举个例子,最近流行歌曲比赛,什么《中国好声音》,《中国好歌曲》什么的,对于一个参赛者而言...
  • u010349169
  • u010349169
  • 2014年02月09日 23:57
  • 5840

设计模式六大原则和每个原则所体现的设计模式

 参考文献:设计模式六大原则   --http://www.uml.org.cn/sjms/201211023.asp 设计模式六大原则   2013-01-25 15:...
  • yangzishiw
  • yangzishiw
  • 2015年03月04日 20:50
  • 918

Head First设计模式:(三)装饰者模式

星巴兹咖啡准备更新订单系统,以合乎他们的饮料供应需求。 他们原先的类设计为: 这样的订单系统没有办法考虑到咖啡调料的部分,把加入不同调料的咖啡看做不同的类会导致类爆炸(每个类的cost方法计算...
  • lissdy
  • lissdy
  • 2012年05月06日 19:31
  • 3041

设计模式(一)设计六大原则

1. 单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因。 从这句定义我们很难理解它的含义,通俗讲就是我们不要让一个类承担过多的职责。如果一个类承担的职责过多,就...
  • itachi85
  • itachi85
  • 2016年01月10日 16:44
  • 9038

设计模式系列之四:装饰者模式(Decorator Pattern)

v/:* {behavior:url(#default#VML);}o/:* {behavior:url(#default#VML);}w/:* {behavior:url(#default#VML)...
  • hillspring
  • hillspring
  • 2008年07月04日 14:40
  • 8425
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式学习之路-装饰者模式(附设计原则)
举报原因:
原因补充:

(最多只允许输入30个字)