博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式学习之路-装饰者模式(附设计原则)
阅读量:4166 次
发布时间:2019-05-26

本文共 4855 字,大约阅读时间需要 16 分钟。

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

第一个设计原则:

单一职责原则(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:

你可能感兴趣的文章
构造函数、析构函数是否要声明为虚函数的问题
查看>>
C++中的虚函数
查看>>
Mysql数据库创建用户
查看>>
一套华为面试题
查看>>
Linux下的多线程编程
查看>>
堆和栈
查看>>
算法的稳定性
查看>>
/dev/null 2>&1 解释
查看>>
进程和线程的区别
查看>>
Mysql索引优化(动态网站优化)
查看>>
MySql索引优化注意
查看>>
数据库查询优化原则
查看>>
sed实例解析
查看>>
NP完全问题
查看>>
如何让new操作符不分配内存,只调用构造函数
查看>>
50个sql语句
查看>>
写得蛮好的linux学习笔记
查看>>
SQL语句集锦【强力推荐!】
查看>>
两阶段提交协议
查看>>
数据库事务和锁
查看>>