星期一, 3月 23, 2015

[DP] 策略模式

根據 Head First Design Pattern 書本內容,來練習策略模式

[DP] 策略模式-HF-1

HeadFirst Project - Dock Class
namespace HeadFirst
{
    #region Dock 相關
    public class Dock
    {
        IFlyBehaivor flyBehavior;

        public void performFly()
        {
            flyBehavior.fly();
        }

        public void setFly(IFlyBehaivor fb)
        {
            flyBehavior = fb;
        }

        IQuackBehavior quackBehavior;
        public void performQuck()
        {
            quackBehavior.quack();
        }

        public void setQuack (IQuackBehavior qb)
        {
            quackBehavior = qb;
        }

        // 預設全部的 dock 都不會飛也不會叫
        public Dock()
        {
            setFly(new FlyNoWay());
            setQuack(new MuteQuack());
        }
    }

    public class MallardDuck : Dock
    {
        // 綠頭鴨預設值
        public MallardDuck()
        {
            setFly(new FlyWithWings());
            setQuack(new Quack());
        }
    }

    public class ModelDock : Dock
    {
        // 建構子用 Dock 預設值
    }
    #endregion

    #region Quack 相關
    public class MuteQuack : IQuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("<< Silence >>");
        }
    }

    public class Squeak : IQuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("Squeak");
        }
    }

    public class Quack : IQuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("Quack");
        }
    }

    public interface IQuackBehavior
    {
        void quack();
    } 
    #endregion

    #region Fly 相關
    public class FlyRockPowered : IFlyBehaivor
    {
        public void fly()
        {
            Console.WriteLine("I'm flying with a rocket");
        }
    }

    public class FlyNoWay : IFlyBehaivor
    {
        public void fly()
        {
            Console.WriteLine("I can't fly");
        }
    }

    public class FlyWithWings : IFlyBehaivor
    {
        public void fly()
        {
            Console.WriteLine("I'm flying!!");
        }
    }

    public interface IFlyBehaivor
    {
        void fly();
    }  
    #endregion
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
        <add key ="FlyRockPowered" value="HeadFirst.FlyRockPowered,HeadFirst"/>
    </appSettings>
</configuration>
HeadFirstDemo Project - Program.cs
using HeadFirst;

namespace HeadFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===== 綠頭鴨測試 =====");
            Dock mallard = new MallardDuck();
            mallard.performFly();
            mallard.performQuck();

            Console.WriteLine("===== 模型鴨測試 =====");
            Dock model = new ModelDock();

            Console.WriteLine("===== 原始能力 =====");
            model.performFly() ;
            model.performQuck();

            Console.WriteLine("===== HeadFirst 設定 =====");
            model.setFly(new FlyRockPowered());
            model.performFly() ;

            Console.WriteLine("===== 遠距教學設定 =====");
            model.setFly(GetFlyBehavior());
            model.performFly();
        }

        static IFlyBehaivor GetFlyBehavior()
        {
            string setting = System.Configuration.ConfigurationSettings.AppSettings["FlyRockPowered"];
            string[] arr = setting.Split(',');
            string dllName = arr[1];
            string className = arr[0];
            IFlyBehaivor fb = (IFlyBehaivor)System.Reflection.Assembly.Load(dllName).CreateInstance(className);
            return fb;
        }
    }
}
[DP] 策略模式-HF-2

星期一, 3月 16, 2015

[DP] 策略模式

了解策略模式時,發現這段 Youtube 教學影片,是利用折扣來說明,那就拿折扣來練習。

[Design Patern] 策略模式-1

ShoppingMall - Mall Class
namespace ShoppingMall
{
    public class Mall
    {
        public string MallName { get; set; }
        public IDiscount DiscountBehavor { get; set; }

        public decimal calPrice(decimal BillTotal)
        {
            return DiscountBehavor.Discount(BillTotal);
        }
    }

    public class Disc50 : IDiscount
    {
        public decimal Discount(decimal BillTotal)
        {
            return Math.Round(BillTotal * 5 / 10, 0, MidpointRounding.AwayFromZero);
        }

        public string Descript
        {
            get { return "5 折"; }
        }
    }

    public class Disc88 :IDiscount
    {
        public decimal Discount(decimal BillTotal)
        {
            return Math.Round(BillTotal * 88 / 100, 0, MidpointRounding.AwayFromZero);
        }

        public string Descript
        {
            get { return "88 折"; }
        }
    }

    public class Coupon1000 : IDiscount
    {
        public string Descript
        {
            get { return "買萬送千"; }
        }

        public decimal Discount(decimal BillTotal)
        {
            if (BillTotal > 10000)
            BillTotal -= 1000;
            return BillTotal;
        }
    }

    public interface IDiscount
    {
        string Descript { get; }
        decimal Discount(decimal BillTotal);
    }
}
ShoppingMallDemo - Web.Config
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <appSettings>
    <add key="discount" value="ShoppingMall.Coupon1000,ShoppingMall"/>
  </appSettings>
</configuration>

ShoppingMallDemo - cs 檔
using ShoppingMall;

public partial class _Default : System.Web.UI.Page
{
    protected void btnCal_Click(object sender, EventArgs e)
    {

        Mall mall = new Mall();
        IDiscount disc = GetDiscount();
        mall.DiscountBehavor = disc;

        lblPay.Text = mall.calPrice(Convert.ToDecimal(txtBillTotal.Text)).ToString();
        lblDisc.Text = disc.Descript;
    }

    IDiscount GetDiscount()
    {
        string setting = System.Configuration.ConfigurationManager.AppSettings["discount"];
        string[] arr = setting.Split(',');
        string dllName = arr[1];
        string className = arr[0];
        IDiscount disc = (IDiscount)System.Reflection.Assembly.Load(dllName).CreateInstance(className);

        return disc;
    }
}
[Design Patern] 策略模式-2

星期一, 3月 09, 2015

[C#] Event 練習

利用最低薪資(假設是 20,000)來練習建立 class 的 event

[C#] Event 練習-1

星期五, 3月 06, 2015

[SQL] 重疊天數分析

論壇問題
希望計算每個人在日期區間內的實際天數有幾天,但會遇到日期重複的問題,不知道該如何處理
IF OBJECT_ID('Datas') IS NOT NULL 
    DROP TABLE Datas

CREATE TABLE Datas 
(
    ID char(1),
    StartDate date,
    EndDate date
)

INSERT INTO Datas VALUES
    ('A','20140101','20140115'),
    ('A','20140114','20140117'),
    ('B','20140215','20140220'),
    ('B','20140220','20140225'),
    ('C','20140301','20140305'),
    ('C','20140320','20140321');
  • 原始資料
[SQL] 重疊天數分析-1
  • 呈現結果
[SQL] 重疊天數分析-3

傳統作法
;
WITH cteStartDate AS
(
    SELECT 
        DISTINCT ID, startdate
    FROM Datas AS S1
    WHERE NOT EXISTS
    (
        SELECT * 
        FROM Datas AS S2 
        WHERE S2.ID = S1.ID
            AND S2.startdate < S1.startdate
            AND S2.enddate >= S1.StartDate
    )
)
,
cteEndDate AS
(
    SELECT DISTINCT ID, enddate
    FROM Datas AS S1
    WHERE NOT EXISTS
    (
        SELECT * 
        FROM Datas AS S2
        WHERE S2.ID = S1.ID
            AND S2.enddate > S1.enddate
            AND S2.startdate <= S1.enddate)
)
SELECT
    ID,
    startdate,
    (
        SELECT MIN(enddate)
        FROM cteEndDate AS E
        WHERE E.ID = S.ID
            AND enddate >= startdate
    ) AS enddate
FROM cteStartDate AS S

星期一, 3月 02, 2015

[C#] Delegate 練習 2

Delegate 簡易練習
public partial class _Default : System.Web.UI.Page
{

    delegate string demo(string Name);
 
    class Say
    {

        public static string SayHello (string name)
        {
            return string.Format("Hello {0}", name);
        }

        public static string HelloHey (string name)
        {
            return string.Format("Hey {0}", name);
        }
    }

    protected void btnRun_Click(object sender, EventArgs e)
    {
        demo d1 = new demo(Say.SayHello);
        lblResult.Text = d1("JengTing") + "<br>";
        demo d2 = new demo(Say.HelloHey);
        lblResult.Text += d2("JengTing") + "<br>";  
    }
}

[C#] Delegate 練習 2