日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

装饰模式【设计模式学习-03】

發(fā)布時(shí)間:2023/12/9 asp.net 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 装饰模式【设计模式学习-03】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Definition

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

?

Frequency of use:??Medium

裝飾模式的UML類圖如下:

?

一個(gè)生動(dòng)的例子:Pizza(手抓餅)

?

Component:

namespace DecoratorDemo {public abstract class Pizza{public string Description { get; set; }public abstract string GetDescription();public abstract double CalculateCost();} }

?

ConcreteComponent:

using System;namespace DecoratorDemo {public class LargePizza : Pizza{public LargePizza(){Description = "Large Pizza";}public override string GetDescription(){return Description;}public override double CalculateCost(){return 9.00;}} }using System;namespace DecoratorDemo {public class MediumPizza : Pizza{public MediumPizza(){Description = "Medium Pizza";}public override string GetDescription(){return Description;}public override double CalculateCost(){return 6.00;}} }using System;namespace DecoratorDemo {public class SmallPizza : Pizza{public SmallPizza(){Description = "Small Pizza";}public override string GetDescription(){return Description;}public override double CalculateCost(){return 3.00;}} }

Decorator

using System;namespace DecoratorDemo {public class PizzaDecorator : Pizza{protected Pizza _pizza;public PizzaDecorator(Pizza pizza){_pizza = pizza;}public override string GetDescription(){return _pizza.Description;}public override double CalculateCost(){return _pizza.CalculateCost();}} }

ConcreteDecorator:

using System;namespace DecoratorDemo {public class Cheese : PizzaDecorator{public Cheese(Pizza pizza): base(pizza){Description = "Cheese";}public override string GetDescription(){return String.Format("{0}, {1}", _pizza.GetDescription(), Description);}public override double CalculateCost(){return _pizza.CalculateCost() + 1.25;}} }using System;namespace DecoratorDemo {public class Ham : PizzaDecorator{public Ham(Pizza pizza): base(pizza){Description = "Ham";}public override string GetDescription(){return String.Format("{0}, {1}", _pizza.GetDescription(), Description);}public override double CalculateCost(){return _pizza.CalculateCost() + 1.00;}} }using System;namespace DecoratorDemo {public class Peppers : PizzaDecorator{public Peppers(Pizza pizza): base(pizza){Description = "Peppers";}public override string GetDescription(){return String.Format("{0}, {1}", _pizza.GetDescription(), Description);}public override double CalculateCost(){return _pizza.CalculateCost() + 2.00;}} }

?

Program:

using System;namespace DecoratorDemo {class Program{static void Main(string[] args){Pizza largePizza = new LargePizza();largePizza = new Cheese(largePizza);largePizza = new Ham(largePizza);largePizza = new Peppers(largePizza);Console.WriteLine(largePizza.GetDescription());Console.WriteLine("{0:C2}", largePizza.CalculateCost());Console.ReadKey();}} }

DebugLZQ: ?手抓餅+奶酪+火腿+辣醬

?

通過(guò)使用裝飾模式,可以在運(yùn)行時(shí)動(dòng)態(tài)地?cái)U(kuò)充一個(gè)類的功能。

原理是:增加一個(gè)修飾類包裹原來(lái)的類。裝飾類實(shí)現(xiàn)新的功能,但是,在不需要用到新功能的地方,它可以直接調(diào)用原來(lái)的類中的方法。修飾類必須和原來(lái)的類有相同的接口。

修飾模式是類繼承的另外一種選擇。類繼承在編譯時(shí)候增加行為,而裝飾模式是在運(yùn)行時(shí)增加行為。

當(dāng)有幾個(gè)相互獨(dú)立的功能需要擴(kuò)充時(shí),這個(gè)區(qū)別就變得很重要。在有些面向?qū)ο蟮木幊陶Z(yǔ)言中,類不能在運(yùn)行時(shí)被創(chuàng)建,通常在設(shè)計(jì)的時(shí)候也不能預(yù)測(cè)到有哪幾種功能組合。這就意味著要為每一種組合創(chuàng)建一個(gè)新類。相反,修飾模式是面向運(yùn)行時(shí)候的對(duì)象實(shí)例的,這樣就可以在運(yùn)行時(shí)根據(jù)需要進(jìn)行組合。

其示例性代碼:

using System;namespace DoFactory.GangOfFour.Decorator.Structural {/// <summary>/// MainApp startup class for Structural /// Decorator Design Pattern./// </summary>class MainApp{/// <summary>/// Entry point into console application./// </summary>static void Main(){// Create ConcreteComponent and two DecoratorsConcreteComponent c = new ConcreteComponent();ConcreteDecoratorA d1 = new ConcreteDecoratorA();ConcreteDecoratorB d2 = new ConcreteDecoratorB();// Link decorators d1.SetComponent(c);d2.SetComponent(d1);d2.Operation();// Wait for user Console.ReadKey();}}/// <summary>/// The 'Component' abstract class/// </summary>abstract class Component{public abstract void Operation();}/// <summary>/// The 'ConcreteComponent' class/// </summary>class ConcreteComponent : Component{public override void Operation(){Console.WriteLine("ConcreteComponent.Operation()");}}/// <summary>/// The 'Decorator' abstract class/// </summary>abstract class Decorator : Component{protected Component component;public void SetComponent(Component component){this.component = component;}public override void Operation(){if (component != null){component.Operation();}}}/// <summary>/// The 'ConcreteDecoratorA' class/// </summary>class ConcreteDecoratorA : Decorator{public override void Operation(){base.Operation();Console.WriteLine("ConcreteDecoratorA.Operation()");}}/// <summary>/// The 'ConcreteDecoratorB' class/// </summary>class ConcreteDecoratorB : Decorator{public override void Operation(){base.Operation();AddedBehavior();Console.WriteLine("ConcreteDecoratorB.Operation()");}void AddedBehavior(){}} } View Code

?

下面再給出一個(gè)示例程序,來(lái)自程杰的大話設(shè)計(jì)模式:

View Code using System;
using System.Collections.Generic;
using System.Text;

namespace 裝飾模式
{
class Program
{
static void Main(string[] args)
{
Person xc = new Person("小菜");

Console.WriteLine("\n第一種裝扮:");

Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirts dtx = new TShirts();

pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();

Console.WriteLine("\n第二種裝扮:");

LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();

px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();

Console.WriteLine("\n第三種裝扮:");
Sneakers pqx2 = new Sneakers();
LeatherShoes px2 = new LeatherShoes();
BigTrouser kk2 = new BigTrouser();
Tie ld2 = new Tie();

pqx2.Decorate(xc);
px2.Decorate(pqx);
kk2.Decorate(px2);
ld2.Decorate(kk2);

ld2.Show();

Console.Read();
}
}

//Person類
class Person
{
public Person()
{ }

private string name;
public Person(string name)
{
this.name = name;
}

public virtual void Show()
{
Console.WriteLine("裝扮的{0}", name);
}
}

//裝飾類
class Finery : Person
{
protected Person component;

//打扮
public void Decorate(Person component)
{
this.component = component;
}

public override void Show()
{
if (component != null)
{
component.Show();
}
}
}

//具體裝飾類
class TShirts : Finery
{
public override void Show()
{
Console.Write("大T恤 ");
base.Show();
}
}

class BigTrouser : Finery
{
public override void Show()
{
Console.Write("垮褲 ");
base.Show();
}
}

class Sneakers : Finery
{
public override void Show()
{
Console.Write("破球鞋 ");
base.Show();
}
}

class Suit : Finery
{
public override void Show()
{
Console.Write("西裝 ");
base.Show();
}
}

class Tie : Finery
{
public override void Show()
{
Console.Write("領(lǐng)帶 ");
base.Show();
}
}

class LeatherShoes : Finery
{
public override void Show()
{
Console.Write("皮鞋 ");
base.Show();
}
}
}

?

使用裝飾模式需要注意的地方:

◇在發(fā)生“類爆炸”的情況下,應(yīng)及時(shí)反思工程的設(shè)計(jì);

◇在類中,不要過(guò)多的將“是否具有某種裝飾”用boolean來(lái)表示;

◇Decorator(裝飾)模式的關(guān)鍵在于“動(dòng)態(tài)地實(shí)現(xiàn)功能擴(kuò)展”;

◇裝飾器的安裝順序很重要,應(yīng)努力做到裝飾器的安裝順序不影響最終的裝飾效果。

?

應(yīng)用實(shí)例:

裝備大兵!無(wú)任何裝備時(shí)(核心功能)可以用拳腳搏擊;裝備了步槍,可以正常射擊;裝備了重機(jī)槍,可以掃射;裝備了火箭筒,可以防空。

類圖:

代碼實(shí)現(xiàn):

using System;namespace DecoratorPattern {/// <summary>/// MainApp startup class for Structural /// Observer Design Pattern./// </summary>class MainApp{static void Main(string[] args){// 定義新兵Soldier soldier = new Soldier();// 三種裝備RifleEquipment rifle = new RifleEquipment();MachineGunEquipment machineGun = new MachineGunEquipment();RocketGunEquipment rocketGun = new RocketGunEquipment();// 將三種裝備全部交給新兵 rifle.SetComponent(soldier);machineGun.SetComponent(rifle);rocketGun.SetComponent(machineGun);// 攻擊,除了拳腳功夫外,新兵還可以使用步槍,機(jī)槍,火箭炮.最終執(zhí)行的是rocketGun.Attack(). rocketGun.Attack();Console.Read();}}/// <summary>/// 裝備類,相當(dāng)于Component/// </summary>public abstract class Equipment{public abstract void Attack();}/// <summary>/// 士兵類,繼承自Equipment/// </summary>public class Soldier : Equipment{public Soldier(){// 構(gòu)造函數(shù) }/// <summary>/// 沒(méi)有任何武器裝備下的核心功能/// </summary>public override void Attack(){Console.WriteLine("用拳腳攻擊!");}}public abstract class EquipDecorator : Equipment{protected Equipment equipment;/// <summary>/// 增加裝備,使用該方法來(lái)動(dòng)態(tài)地給士兵增加裝備/// </summary>/// <param name="equipment"></param>public void SetComponent(Equipment equipment){this.equipment = equipment;}/// <summary>/// 攻擊/// </summary>public override void Attack(){//如果有裝備,就用裝備進(jìn)行攻擊if (equipment != null){equipment.Attack();}}}/// <summary>/// 步槍/// </summary>public class RifleEquipment : EquipDecorator{public override void Attack(){base.Attack();Console.WriteLine("步槍射擊,啪!");}}/// <summary>/// 機(jī)槍/// </summary>public class MachineGunEquipment : EquipDecorator{public override void Attack(){base.Attack();Console.WriteLine("機(jī)槍掃射,突突突!");}}/// <summary>/// 火箭筒/// </summary>public class RocketGunEquipment : EquipDecorator{public override void Attack(){base.Attack();Console.WriteLine("火箭炮射擊,唰......!");}} }

輸出結(jié)果:

?

優(yōu)點(diǎn)

 1 每個(gè)裝飾對(duì)象只關(guān)心自己的功能,不需要關(guān)心如何被添加到對(duì)象鏈當(dāng)中。它是由Decorator的SetComponent方法來(lái)實(shí)現(xiàn)的,因而它們的職責(zé)是單一的。

 2 類的核心職責(zé)與動(dòng)態(tài)添加的職責(zé)是分離的。如果再向主類中添加新的功能,一是違反了開(kāi)放封閉原則,二是增加了主類的復(fù)雜度。

 3?比靜態(tài)繼承更靈活?與對(duì)象的靜態(tài)繼承相比,Decorator模式提供了更加靈活的向?qū)ο筇砑勇氊?zé)的方式,可以使用添加和分離的方法,用裝飾在運(yùn)行時(shí)刻增加和刪除職責(zé).

缺點(diǎn)

 1?產(chǎn)生許多小對(duì)象,采用Decorator模式進(jìn)行系統(tǒng)設(shè)計(jì)往往會(huì)產(chǎn)生許多看上去類似的小對(duì)象,這些對(duì)象僅僅在他們相互連接的方式上有所不同。

適用場(chǎng)景

 1 當(dāng)需要為已有功能動(dòng)態(tài)地添加更多功能時(shí)。

 2 類的核心功能無(wú)需改變,只是需要添加新的功能時(shí)。

?

?

總結(jié)

以上是生活随笔為你收集整理的装饰模式【设计模式学习-03】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。