装饰模式

装饰模式

装饰模式是一种用于代替继承的技术,达到无需定义子类却能够给对象动态增长职责的效果。让对象之间的继承关系转变为关联关系。算法

装饰模式能够在不改变已有对象自己的功能的基础上给对象增长额外的新职责,比如平常生活中的照片,能够给照片使用相框,使之具备防潮的功能,可是这样并无改变照片自己,这即是装饰模式。ide

装饰模式的结构

image.png

  • Component(抽象构件):具体构件和抽象装饰类的父类,声明了具体构件中所需的业务方法,引入该抽象层能够将未被装饰的对象和装饰后的对象统一处理。
  • SpecificComponent(具体构件):派生自抽象构件,用于定义具体的构件对象,实现了抽象构件中的方法,装饰类能够给它增长额外的职责。
  • Decorator(抽象装饰类):派生自抽象构件,用于给具体构件增长职责,一般具体职责实如今抽象装饰类的子类中。内部维护一个抽象构件对象的引用,经过这个引用能够调用装饰以前对象的方法,并经过其子类扩展该方法达到装饰的目的。
  • SpecificDecorator(具体装饰类):派生自抽象装饰类,负责给构件添加新职责。每一个具体装饰类都定义了新的行为,它能够调用在抽象装饰类中的方法,也能够增长新的方法。

装饰模式的实现

  • 抽象构件
abstract class Component
{
    public abstract void Operation();
}
  • 具体构件(一般只实现基本功能,复杂功能经过装饰类扩展)
class SpecificComponent : Component
{
    public override void Operation()
    {
        //实现基本功能
    }
}
  • 抽象装饰类(核心)
class Decorator : Component
{
    private Component m_Component;

    public Decorator(Component component)
    {
        this.m_Component = component;
    }

    public override void Operation()
    {
        //调用原有业务的方法,并未真正装饰,具体装饰交给子类
        this.m_Component.Operation();
    }
}
  • 具体装饰类
class SpecificDecorator : Decorator
{
    public SpecificDecorator(Component component) : base(component) { }

    public override void Operation()
    {
        //调用原有的业务方法
        base.Operation();
        //调用新增的业务方法
        this.AddedBehavior();
    }

    //新增业务方法
    private void AddedBehavior()
    {
        //具体装饰
    }
}

示例场景

开发一个能够对字符串进行加密的数据加密模块。提供最简单的加密算法字母移动实现;提供稍微复杂的逆向输出加密;提供更为高级的求模加密。用户先使用最简单的加密算法进行加密,若是以为还不够能够对加密后的结果进行二次加密甚至三次加密,使用装饰模式设计。性能

代码this

abstract class EncryptionComponent
{
    public abstract void EncryptionOperation(string str);
}

class Encryption : EncryptionComponent
{
    public override void EncryptionOperation(string str)
    {
        Console.WriteLine("对字符串: {0}进行位移加密", str);
    }
}

//抽象装饰类
class ComponentDecorator : EncryptionComponent
{
    private EncryptionComponent m_Component;

    public ComponentDecorator(EncryptionComponent component)
    {
        this.m_Component = component;
    }

    public override void EncryptionOperation(string str)
    {
        this.m_Component.EncryptionOperation(str);
    }
}

//逆序加密装饰类(具体装饰类)
class ReverseDecorator : ComponentDecorator
{
    public ReverseDecorator(EncryptionComponent component) : base(component) { }

    public override void EncryptionOperation(string str)
    {
        base.EncryptionOperation(str);
        this.ReverseEncryption(str);
    }

    private void ReverseEncryption(string str)
    {
        Console.WriteLine("对字符串: {0}进行逆序加密", str);
    }
}

//求模加密装饰类(具体装饰类)
class ModDecorator : ComponentDecorator
{
    public ModDecorator(EncryptionComponent component) : base(component) { }

    public override void EncryptionOperation(string str)
    {
        base.EncryptionOperation(str);
        this.ModEncryption(str);
    }

    private void ModEncryption(string str)
    {
        Console.WriteLine("对字符串: {0}进行求模加密", str);
    }
}

不进行加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    //不进行装饰
    component.EncryptionOperation("装饰模式");
    Console.ReadKey();
}

运行结果
image.png加密

同时使用逆序加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    EncryptionComponent decorate = new ReverseDecorator(component);
    decorate.EncryptionOperation("装饰模式");
    Console.ReadKey();
}

运行结果
image.pngspa

同时使用三种加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    EncryptionComponent decorate = new ReverseDecorator(component);
    decorate = new ModDecorator(decorate);
    decorate.EncryptionOperation("装饰模式");
    Console.ReadKey();
}

运行结果
image.png设计

装饰模式的优势

  • 相对继承而言,扩展更加灵活。
  • 能够动态扩展对象的职责。
  • 能够对一个对象进行屡次装饰,经过不一样的具体装饰类以及装饰类的各自排列组合可以创造出多种不一样的行为组合。
  • 具体构件类和具体装饰类能够独立变化,互不影响。

装饰模式的缺点

  • 装饰模式设计会致使系统中出现不少小对象,占用更多的系统资源,影响程序性能。
  • 相对继承更加灵活却也更加复杂容易出错,对于屡次装修的对象,调试时可能须要逐级定位错误,较为繁琐。

应用场景

  • 在不影响其它对象的状况下须要动态的给单个对象添加职责。
  • 不能采用继承的方式对系统进行扩展或者采用继承不利于系统的扩展和维护时能够使用装饰模式。
相关文章
相关标签/搜索