用织梦做网站有什么公司会要,国外做装修设计网站,全球速卖通中文官网,丰镇网络推广#x1f680;介绍 在装饰者模式中#xff0c;装饰者类通常对原始类的功能进行增强或减弱。这种模式是在不必改变原始类的情况下#xff0c;动态地扩展一个对象的功能。这种类型的设计模式属于结构型模式#xff0c;因为这种模式涉及到两个类型之间的关系#xff0c;这两个…介绍 在装饰者模式中装饰者类通常对原始类的功能进行增强或减弱。这种模式是在不必改变原始类的情况下动态地扩展一个对象的功能。这种类型的设计模式属于结构型模式因为这种模式涉及到两个类型之间的关系这两个类型是组合在一起的这种组合关系通常是通过继承来实现的。 装饰者模式的主要优点是可以在不修改原始类的情况下通过使用单个类来包装其对象动态地扩展一个对象的功能。其主要缺点是装饰者模式会导致设计中出现很多小类如果过度使用会使程序变得复杂。 装饰 Decorator 模式中的角色 抽象构件Component角色 定义一个抽象接口以规范准备接收附加责任的对象。 具体构件Concrete Component角色 实现抽象构件通过装饰角色为其添加一些职责。抽象装饰Decorator角色 继承或实现抽象构件并包含具体构件的实例可以通过其子类扩展具体构件的功能。 具体装饰ConcreteDecorator角色 实现抽象装饰的相关方法并给具体构件对象添加附加的责任。 案例 我们使用一个案例来对快餐店的点餐功能进行改进快餐店有炒面、炒饭这些快餐可以额外附加鸡蛋、培根这些配菜加配菜需要额外加钱每个配菜的价钱通常不太一样那么计算总价就会显得比较麻烦这时候我们就可以使用装饰者模式在不改变原始类的情况下动态扩展对象功能。 首先创建一个最基本的主食抽象类定义了价格和类型两个属性以及获取费用和获取类型两个抽象方法 public abstract class FastFood
{/// summary/// 价格/// /summarypublic float _price { get; set; }/// summary/// 类型/// /summarypublic string _desc { get; set; }public FastFood(){}public FastFood(float price, string desc){_price price;_desc desc;}/// summary/// 获取费用/// /summary/// returns/returnspublic abstract float GetCost();/// summary/// 获取类型/// /summary/// returns/returnspublic abstract string GetDesc();
} 然后对于上面的主食抽象类分别增加两个实现类炒饭和炒面在这里通过基类的含有(float price, string desc)参数的构造函数分别对价格和类型赋值如果在此处直接调用了GetDesc那么此时的炒饭和炒粉是什么都还没加的因此我们在重写GetDesc加上了啥都不加字符 /// summary
/// 炒饭
/// /summary
public class FriedRice : FastFood
{public FriedRice() : base(10, 炒饭){}public override float GetCost(){return _price;}public override string GetDesc(){return _desc 啥都不加;}
}/// summary
/// 炒面
/// /summary
public class FriedNoodles : FastFood
{public FriedNoodles() : base(12, 炒面){}public override float GetCost(){return _price;}public override string GetDesc(){return _desc 啥都不加;}
} 创建一个配料抽象类继承于主食抽象类并且定义了一个FastFood主食类型的属性_fastFood /// summary
/// 配料类
/// /summary
public abstract class Garnish : FastFood
{public FastFood _fastFood { get; set; }
} 对配料类做两个实现鸡蛋和培根通过这两个对象我们可以动态地给一个FastFood对象添加鸡蛋或培根并计算出新的价格和描述这就是装饰者模式的核心思想。 在方法中我们再次重写了获取类型和价格的方法。 GetCost()方法是用来计算总价的即鸡蛋或培根的价格加上被装饰对象的价格。 GetDesc()方法是用来获取描述的即鸡蛋或培根的描述加上被装饰对象的描述。 /// summary
/// 添加鸡蛋
/// /summary
public class Egg : Garnish
{public Egg(FastFood fastFood){_fastFood fastFood;_desc 鸡蛋;_price 3;}public override float GetCost(){return _price _fastFood._price;}public override String GetDesc(){return _desc _fastFood._desc;}
}/// summary
/// 添加培根
/// /summary
public class Bacon : Garnish
{public Bacon(FastFood fastFood){_fastFood fastFood;_price 5;_desc 培根;}public override float GetCost(){return _price _fastFood._price;}public override String GetDesc(){return _desc _fastFood._desc;}
} 测试类 class MyClass
{public static void Main(string[] args){//点一份炒饭FastFood riceFood new FriedRice();//花费的价格Console.WriteLine(riceFood.GetDesc() riceFood.GetCost() 元);//点一份炒面FastFood noodleFood new FriedNoodles();//花费的价格Console.WriteLine(noodleFood.GetDesc() noodleFood.GetCost() 元);//点一份加鸡蛋的炒饭FastFood food1 new FriedRice();food1 new Egg(food1);//花费的价格Console.WriteLine(food1.GetDesc() food1.GetCost() 元);//点一份加培根的炒面FastFood food2 new FriedNoodles();food2 new Bacon(food2);//花费的价格Console.WriteLine(food2.GetDesc() food2.GetCost() 元);}
} 运行结果 总结 好处 饰者模式可以带来比继承更加灵活性的扩展功能使用更加方便可以通过组合不同的装饰者对象 来获取具有不同行为状态的多样化的结果。装饰者模式比继承更具良好的扩展性完美的遵循开闭原则继承是静态的附加责任装饰者则是动态的附加责任。 装饰类和被装饰类可以独立发展不会相互耦合装饰模式是继承的一个替代模式装饰模式可以动态扩展一个实现类的功能。 使用场景 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。 不能采用继承的情况主要有两类 第一类是系统中存在大量独立的扩展为支持每一种组合将产生大量的子类使得子类数目爆炸性增长 第二类是因为类定义不能继承如final类 在不影响其他对象的情况下以动态、透明的方式给单个对象添加职责。 当对象的功能要求可以动态地添加也可以再动态地撤销时。