首页 | 网页设计 | w3c标准 | flash动画 | 平面设计 | 经典文章 | 特约专题 | 资源下载 | 健康频道 | 重庆品牌网站 | 留言簿 | 
技术文章  资源下载 经典素材  社区论坛
   
 您现在的位置: vi设计在线 >> 经典文章 >> ccqvi动态 >> 技术应用 >> 正文  
  最新IT信息-C#如何动态地给一个对象添加一些额外的职责         
[ 作者:佚名    转贴自:本站原创    点击数:1378    更新时间:2010/7/6    文章录入:diyinetwork ]

减小字体 增大字体

C#如何动态地给一个对象添加一些额外的职责

 重庆帝一网络建设专家 http://www.diy88.com.cn

动态地给一个对象添加一些额外的职责。就增加功能来说,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("ammot{0}", Ammo)); 
    Console.WriteLine(string.Format("attackt{0}", Attack)); 
    Console.WriteLine(string.Format("speedt{0}", Speed)); 
    Console.WriteLine(string.Format("namet{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"); 
  } 
} 
}

代码执行结果如下图:

代码说明

Weapon是抽象构件角色。

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

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

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

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

何时采用

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

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

实现要点

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

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

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

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

注意事项

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

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

 上一篇文章: 最新IT信息-一代互联网:速度更快容量更大
 下一篇文章: 最新IT信息-系统维护专家也需要专业日志审计与分析工具
发表评论】【告诉好友】【打印此文】【关闭窗口


技术文章  资源下载
经典素材  社区论坛
 中大型美容美发店老…[1061]
 重庆多达学习俄语培…[2288]
 重庆恒祥广告有限公…[1991]
 重庆市南方阻燃电线…[2402]
 重庆舞美灯光音响有…[3145]
 重庆德鼎滤油机有限…[1908]
 重庆民生建材有限公…[2350]
 重庆集元科技有限公…[4128]
 重庆倍润商贸有限公…[2015]
 重庆腾达展览有限公…[3082]
 帝一网络创始人宣…--[3177]
 重庆vi设计在线祝…--[2740]
 重庆帝一网络书生…--[2855]
 馋嘴鸭的起伏和经…--[3001]
 机器感觉“卡”的…--[2929]
 ActionScript3打造…--[5760]
 在ASP文件中读取H…--[7239]
 vi设计经典案例--[63826]
 帅到掉渣-爆笑版勇…--[7066]
 一个女孩写的经典…--[6827]
没有相关文章
 (只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    没有任何评论
设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 重庆网站建设 | 
版权所有: vi设计在线  © 2005-2018 网站备案序号:渝ICP备06003824号
技术支持:帝一网络(重庆网站建设专家)