顯示具有 設計模式 標籤的文章。 顯示所有文章
顯示具有 設計模式 標籤的文章。 顯示所有文章

2013年5月11日 星期六

一秒看破 裝飾者模式 Decorator Pattern

設計模式 (design patterns) 有人覺得很難 有人覺得很神秘

其實他是一種 在特定情境下 使用一些別具巧思的物件導向技巧 的方法

往往直接看定義說明 根本難以理解到底在幹嘛

那不如直接回歸原點 一開始就從[情境]來看看怎麼玩





這回要來玩弄的是 裝飾者模式 (Decorator Pattern)

先拜讀神人文

神人文 其實已經說明得很清楚了 小弟我也不必在此 裝很懂

我的心得是:

當有一群 [本質相近]但又個有些[不盡相同]的東西 的時候 適合使用 裝飾者模式





那就來玩一下吧 我們這麼宅 又覺得 不吃早餐才是一件很嘻哈的事

所以神人舉例的早餐 改成我們熟悉的東東





弄個 武器 抽象類 跟 一些武器


    //武器 抽象類
    public abstract class Weapon
    {
        public string Name = "砂鍋大的鐵拳";

        public virtual string GetName()
        {
            return Name;
        }

        public abstract double AttackPower();
    }

    //
    public class Sword : Weapon
    {
        public Sword()
        {
            base.Name = "";
        }

        public override double AttackPower()
        {
            return 10;
        }
    }

    //
    public class Knife : Weapon
    {
        public Knife()
        {
            base.Name = "";
        }

        public override double AttackPower()
        {
            return 5;
        }
    }




再弄個 強化武器 抽象裝飾者類 跟 一些強化功能


    //強化武器 抽象裝飾者類
    public abstract class StrengthenDecorator : Weapon
    {
        public abstract override double AttackPower();
    }

    //加長
    public class Long : StrengthenDecorator
    {
        private Weapon _weapon;

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

        public override double AttackPower()
        {
            return _weapon.AttackPower() + 5;
        }

        public override string GetName()
        {
            return "加長的" + _weapon.GetName();
        }
    }

    //鋒利
    public class Sharp : StrengthenDecorator
    {
        private Weapon _weapon;

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

        public override double AttackPower()
        {
            return _weapon.AttackPower() + 20;
        }

        public override string GetName()
        {
            return "鋒利的" + _weapon.GetName();
        }
    }

    //劇毒
    public class Toxic : StrengthenDecorator
    {
        private Weapon _weapon;

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

        public override double AttackPower()
        {
            return _weapon.AttackPower() + 100;
        }

        public override string GetName()
        {
            return "劇毒的" + _weapon.GetName();
        }
    }

    //傳說
    public class Legendary : StrengthenDecorator
    {
        private Weapon _weapon;

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

        public override double AttackPower()
        {
            return _weapon.AttackPower() + 9999;
        }

        public override string GetName()
        {
            return "傳說的" + _weapon.GetName();
        }
    }




最後 拉些 可有可無的 UI 看看效果



    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Weapon weapon;

        private void Sword_rb_CheckedChanged(object sender, System.EventArgs e)
        {
            weapon = new Sword();
            Log(weapon.GetName(), weapon.AttackPower());
            Knife_rb.Enabled = Sword_rb.Enabled = false;
        }

        private void Knife_rb_CheckedChanged(object sender, System.EventArgs e)
        {
            weapon = new Knife();
            Log(weapon.GetName(), weapon.AttackPower());
            Knife_rb.Enabled = Sword_rb.Enabled = false;
        }

        private void GetLong_Click(object sender, System.EventArgs e)
        {
            weapon = new Long(weapon);
            Log(weapon.GetName(), weapon.AttackPower());
        }

        private void GetSharp_Click(object sender, System.EventArgs e)
        {
            weapon = new Sharp(weapon);
            Log(weapon.GetName(), weapon.AttackPower());
        }

        private void GetToxic_Click(object sender, System.EventArgs e)
        {
            weapon = new Toxic(weapon);
            Log(weapon.GetName(), weapon.AttackPower());
        }

        private void GetLegendary_Click(object sender, System.EventArgs e)
        {
            weapon = new Legendary(weapon);
            Log(weapon.GetName(), weapon.AttackPower());
        }

        private void Log(string name, double attackPower)
        {
            Log_lb.Text +=
                "勇者OO拾取了 [" + name + "]" +
                "攻擊力:" + attackPower + "" +
                Environment.NewLine;
        }
    }





定番截圖