当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 无废话C#设计模式之十三:Decorator

ASP.NET
asp.net GridView控件中模板列CheckBox全选、反选、取消
asp.net GridView 删除时弹出确认对话框(包括内容提示)
asp.net DropDownList 三级联动下拉菜单实现代码
asp DataTable添加列和行的三种方法
Asp.net 页面调用javascript变量的值
asp.net 长文章通过设定的行数分页
asp.net 定时间点执行任务的简易解决办法
asp.net 页面延时五秒,跳转到另外的页面
asp.net 动态输出透明gif图片
asp.net DataList与Repeater用法区别
asp.net Javascript获取CheckBoxList的value
asp.net程序在调式和发布之间图片路径问题的解决方法
asp.net下生成英文字符数字验证码的代码
asp.net 页面版文本框智能提示JSCode (升级版)
ASP.NET URL伪静态重写实现方法
ASP.NET 2.0 中Forms安全认证
asp.net 动态添加多个用户控件
asp.net Repeater显示父子表数据,无闪烁
asp.net 无法获取的内部内容,因为该内容不是文本 的解决方法
asp.net GridView排序简单实现

ASP.NET 中的 无废话C#设计模式之十三:Decorator


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 94 ::
收藏到网摘: n/a

  本系列文章将向大家介绍一下C#的设计模式,此为第十三篇文章,相信对大家会有所帮助的。废话不多说,继续来看。

  意图

  动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

  场景

  在设计网络游戏的武器系统时,开始并没有考虑到武器的强化和磨损。之后,策划人员说希望给游戏增加强化系统和修理系统,那么我们的武器类型就需要对外提供强化、磨损、修理等方法了。发生这种改动是我们最不愿意看到的,按照设计原则,我们希望功能的扩展尽可能不要修改原来的程序。你可能会想到使用继承来实现,但是策划人员的需求是有的武器能磨损能修理,不能强化,有的武器能强化,但是不会磨损,有的武器既能强化还能磨损和修理。遇到这样的情况,继承的方案可能不适合了,一来继承的层次可能会很多,二来子类的数量可能会很多。

  由此,引入装饰模式来解决这个问题。装饰模式使得我们能灵活赋予类额外的职责,并且使得设计和继承相比更合理。

  示例代码

  using System;
  using System.Collections.Generic;
  using System.Text;
  namespace DecoratorExample
  {
  class Program
  {
  static void Main(string[] args)
  {
  Weapon w = new Rifle();
  w.ShowInfo();
  Enhance enhancedWeapon = new Enhance(w);
  enhancedWeapon.EnhanceAmmo();
  enhancedWeapon.ShowInfo();
  Wear wornWeapon = new Wear(w);
  wornWeapon.WearByRate(0.8);
  wornWeapon.ShowInfo();
  }
  }
  abstract class Weapon
  {
  private double ammo;
  public double Ammo
  {
  get { return ammo; }
  set { ammo = value; }
  }
  private double attack;
  public double Attack
  {
  get { return attack; }
  set { attack = value; }
  }
  private double speed;
  public double Speed
  {
  get { return speed; }
  set { speed = value; }
  }
  private string name;
  public string Name
  {
  get { return name; }
  set { name = value; }
  }
  public abstract void ShowInfo();
  }
  class Rifle : Weapon
  {
  public Rifle()
  {
  this.Ammo = 100;
  this.Attack = 10;
  this.Speed = 5;
  this.Name = "Rifle";
  }
  public override void ShowInfo()
  {
  Console.WriteLine(string.Format("ammo\t{0}", Ammo));
  Console.WriteLine(string.Format("attack\t{0}", Attack));
  Console.WriteLine(string.Format("speed\t{0}", Speed));
  Console.WriteLine(string.Format("name\t{0}", Name));
  }
  }
  abstract class Decorator : Weapon
  {
  protected Weapon w;
  public Decorator(Weapon w)
  {
  this.w = w;
  }
  public override void ShowInfo()
  {
  w.ShowInfo();
  }
  }
  class Enhance : Decorator
  {
  public Enhance(Weapon w) : base(w) { }
  public void EnhanceAmmo()
  {
  w.Ammo += 20;
  Console.WriteLine(">>>>>>>>>>>>Enhanced");
  }
  }
  class Wear : Decorator
  {
  public Wear(Weapon w) : base(w) { }
  public void WearByRate(double rate)
  {
  w.Speed = w.Speed * rate;
  w.Attack = w.Attack * rate;
  Console.WriteLine(">>>>>>>>>>>>Worn");
  }
  }
  }

  代码执行结果如下图:

  无废话C#设计模式之十三:Decorator_软晨学习网RuanChen.Com转载

  代码说明

  Weapon是抽象构件角色。

  Rifle是具体构件角色,实现抽象构件的接口。

  Decorator是装饰角色。装饰角色有两个特点,一是继承了抽象构件的接口,二是有一个构件角色的实例。

  Enhance和Wear是具体装饰角色,它们负责给构件附加责任。

  客户端在使用装饰角色的时候并没有针对抽象构件进行编程,因为我们确实需要使用具体装饰角色提供的额外方法,这种类型的装饰叫做半透明装饰。

  何时采用

  从代码角度来说,如果你觉得由于功能的交叉扩展不会导致非常多的子类或者非常多的继承层次的话可以考虑装饰模式。

  从应用角度来说,如果你希望动态给类赋予或撤销一些职责,并且可以任意排列组合这些职责的话可以使用装饰模式。

  实现要点

  让装饰角色还继承抽象构件角色也是装饰模式最大的特点,目的就是给抽象构件增加职责,对外表现为装饰后的构件。

  让装饰角色拥有构件角色实例的目的就是让构件能被多个装饰对象来装饰。

  在具体应用中可以灵活一点,不一定要有抽象构件和装饰角色。但是,装饰对象继承装饰对象并且拥有它实例的两大特点需要体现。

  透明装饰一般通过在基类方法前后进行扩充实现,半透明装饰一般通过新的接口实现。

  注意事项

  装饰模式和桥接模式的区别是,前者是针对功能的扩展,本质上还是一样东西,而后者针对多维护变化。装饰模式的思想在于扩展接口而桥接模式的思想是分离接口。

  装饰类可能会比较琐碎,并且不利于复用,装饰模式在增加了灵活性的同时也降低了封装度,在实际应用中可以和其它模式配合。