关于装饰者模式的一些理解

      装饰者模式,主要是为了解决在对类进行扩展过程中可能出现的子类爆炸,并同时满足“对扩展开放,对修改封闭”的原则。我们以游戏中的武器作为例,游戏中的武器有基本的伤害值,有附加的特效,特效的种类比较多,且同一个武器会带有多种特效,例如伤害增强10%,攻击速度增强20%等等,若采用继承的方式来做,就会产生子类爆炸,同时,如果需要增加一种新的特效的话,就需要修改原来的代码。但是如果采用装饰者模式,就可以比较简单的解决这个问题,在用代码实现之前,我们先画一下模式图。


       装饰者模式中分为这么几种角色,一个是抽象组件,对应途中是weapon类,一个是具体组件,对应各类武器,例如sword类,另一个是抽象装饰类,抽象装饰类也继承于抽象组件,是为了装饰者中有一个实例变量以保存对weapon的引用,最后是具体装饰类,负责添加具体的特性。具体的实现代码如下:

抽象组件:

public abstract class Weapon
{
     public abstract void GetDescription();
}

具体组件:

public class Sword:Weapon
    {
        public override void GetDescription()
        {
            Console.WriteLine("This is a Sword");
        }

    }

抽象装饰类:

public abstract class effect:Weapon
    {
        private Weapon _weapon;

        public effect(Weapon weapon)
        {
            _weapon = weapon;
        }

        public override void GetDescription()
        {
            if(_weapon != null)
            {
                _weapon.GetDescription();
            }
            
        }
    }

具体装饰类(增强10%伤害):

public class EnhanceAttack : effect
    {
        public EnhanceAttack(Weapon weapon):base(weapon)
        {
            
        }

        public override void GetDescription()
        {
            base.GetDescription();
            Console.WriteLine("Add 10% Attack");
        }
    }

具体装饰类(增加10%速度):

public class IncreaseSpeed : effect
    {
        public IncreaseSpeed(Weapon weapon):base(weapon)
        {

        }

        public override void GetDescription()
        {
            base.GetDescription();
            Console.WriteLine("Increase 10% Speed!");
        }

        
    }

具体使用:

static void Main(string[] args)
        {
            // 新建一个Sword对象
            Weapon weapon = new Sword();

            // 对Sword对象添加伤害增强特效
            weapon = new EnhanceAttack(weapon);
            // 对Sword对象再添加增加攻击速度特效
            weapon = new IncreaseSpeed(weapon);
            weapon.GetDescription();
            Console.WriteLine("-----------------------");

            Console.ReadLine();

        }

结果:


如果后期需要增加新的特效,例如按4%伤害吸取生命,则可以再新建一个具体装饰类,而无需更改原先的代码。

       在上面这个例子中,假设让具体装饰类直接继承抽象组件类,将对weapon的引用直接放到具体装饰类中,不需要抽象装饰类也能实现一样的目的,如代码所示:

public class IncreaseSpeed : Weapon
    {
        private Weapon _weapon;

        public IncreaseSpeed(Weapon weapon)
        {
            _weapon = weapon;
        }

        public override void GetDescription()
        {
            _weapon.GetDescription();
            Console.WriteLine("Increase 10% Speed!");
        }

        
    }

       在逻辑不复杂的情况下,用这种方式也能实现一样的功能,但是当功能比较复杂的时候,比如需要按照步骤执行一些操作的时候,则需要将这些步骤放到抽象装饰类,然后在具体装饰类中再根据实际需求装饰每个步骤。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值