设计模式与实例代码:Decorator模式

意图/定义:动态地给一个对象添加一些额外的职责,而这些职责可能以任意的顺序来添加,从而提供了比生成子类更灵活的方法来添加功能

问题:要使用的对象可以提供所需的功能,但可能要为这个对象添加某些功能,这些附加功能可能发生在对象的基础功能之前或之后。

参与者与协作者:被装修者让装修者为自己添加功能,但其不需要了解自己被如何装修。

效果:所添加的功能放在小对象中,可以在被装修者之前或之后动态的添加及装配功能,各层的装饰者只知道自己包装了某个被装饰对象,但其不了解这个被包装对象已经被如何包装,也不知道自己将被如何装修。


实例代码,下面的代码展示了在RPG游戏系统中常见的一个实现。我们的角色需要通过装配不同的衣服、武器、挂件等以获得额外属性或技能,而且我们的衣服或武器也可以再镶嵌不同宝石获取额外的属性。这样的功能通常就可以用装修器模式来实现。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Decorator
{
    /// <summary>
    /// MainApp startup class 
    /// Decorator Design Pattern.
    /// </summary>
    class MainApp
    {
        /// <summary>
        /// Entry point into console application.
        /// </summary>
        static void Main()
        {
            // Create ConcreteComponent and two Decorators
            role r = new role();

            clothes  c = new clothes();
            weapon w = new weapon();
            diamond d = new diamond();
                
            // Link decorators
            c.SetComponent(r);
            w.SetComponent(c);
            d.SetComponent(w);

            d.getRoleAttrbute();

            // Wait for user
            Console.ReadKey();
        }
    }

    /// <summary>
    /// The 'Component' abstract class
    /// </summary>
    abstract class Component
    {
        public abstract int[]  getRoleAttrbute();
    }

    /// <summary>
    /// The 'ConcreteComponent' class
    /// </summary>
    class role : Component
    {
        private int HP;
        private int ATTACK;
        private int DEFEND;

        public role()
        {
            HP = ATTACK = DEFEND = 100;
        }

        public override int[] getRoleAttrbute()
        {
            int[] temp = {HP,ATTACK,DEFEND};

            return temp;
        }
    }

    /// <summary>
    /// The 'Decorator' abstract class
    /// </summary>
    abstract class Decorator : Component
    {
        protected Component component;

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

        public override int[] getRoleAttrbute()
        {            
                return component.getRoleAttrbute();            
        }
    }

    /// <summary>
    /// The 'ConcreteDecoratorA' class
    /// </summary>
    class clothes : Decorator
    {
        public override int[] getRoleAttrbute()
        {
            int[] temp = AddedBehavior();
            Console.WriteLine("clothes: {0:d} {1:d} {2:d}", temp[0],temp[1],temp[2]);
            return temp;
        }

        int[] AddedBehavior()
        {
            int[] temp = base.getRoleAttrbute();
            temp[2] += 10;
            return temp;
        }
    }

    /// <summary>
    /// The 'ConcreteDecoratorB' class
    /// </summary>
    class weapon : Decorator
    {
        public override int[] getRoleAttrbute()
        {            
            int[] temp = AddedBehavior();

            Console.WriteLine("weapon: {0:d} {1:d} {2:d}", temp[0], temp[1], temp[2]);

            return temp;
        }

        int[] AddedBehavior()
        {
            int[] temp = base.getRoleAttrbute();
            temp[1] += 20;

            return temp;
        }
    }

    class diamond : Decorator
    {
        public override int[] getRoleAttrbute()
        {
                        
           int[] temp = AddedBehavior();

            Console.WriteLine("diamond: {0:d} {1:d} {2:d}", temp[0], temp[1], temp[2]);

            return temp;
        }

        int[] AddedBehavior()
        {
            int[] temp = base.getRoleAttrbute();
            temp[0] += 30;

            return temp;
        }

    }
}


在上面的例子中,被装饰类为普通的角色role,其具备基本的三个属性,体力、攻击力、防御力,这三个属性会随着角色不断的装备不同的挂件而进行改变,不同的挂件可以动态的附着在一个被包装的role,并增加其自身的功能。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值