《Head First 設計模式》學習心得
策略模式
定義
策略模式定義了算法族,分別封裝起來。讓他們之間可以相互替換,此模式讓算法的變化獨立於使用算法的客戶。每個行爲接口和它的各個實現組成一個算法族,算法族中的每個具體實現是可以互相替換的。
設計原則:
- 把代碼中將來可能變化的部分抽離出來,獨立封裝;
- 針對接口編程,而不是針對實現編程;
- 多用組合,少用繼承。
兩條原則,說白了都是變與不變的分離,第一條原則其實是目的,第二條原則是手段。
心得
設計的目標是要儘可能的重用代碼,也就是能少幹就少乾點,時間節省下來喝茶聊天也比擼代碼強。實現代碼重用的重要手段是繼承。子類公共的東西,在父類中實現,那麼在子類中就不用再敲一遍代碼了。在現實情況中,會有這種情況,就是某個東西一些子類中有,一些子類中沒有,而且將來說不好新子類中有沒有或者不一樣。那怎麼辦呢?
這部分就是可變的,要抽離出來,每一個功能用一個接口,接口就是功能的抽象,比如飛翔,飛的姿勢有很多種,那麼這個接口就是飛翔。具體的飛翔功能,就用一個具體類去實現這個接口。
在要重用的基類中聲明接口類型的字段,調用接口中的方法。在子類中,給從父類繼承而來的字段賦予具體接口實現。這樣基類就不用老是改變了。
至此基類的結構是這樣的:不變的部分,可變部分的接口;
子類中的結構是這樣的:父類的不變的部分,可變部分的接口的具體對象賦值,擴展的部分。
示例代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 設計模式入門
{
class Program
{
static void Main(string[] args)
{
// 消費子類
var mallardDuck=new MallardDuck();
mallardDuck.SetFlyBehavior(new FlyWithWind());
mallardDuck.SetQuackBehavior(new MallerdDuckQuack());
mallardDuck.PerformQuack();
mallardDuck.PerformFly();
Console.ReadKey();
}
}
#region 以下是變得部分
public class MallardDuck : Duck
{
// 具體的子類
public MallardDuck()
{
}
#region 動態設定類型
public void SetFlyBehavior(IFlyBehavior flyBehavior)
{
FlyBehavior = flyBehavior;
}
public void SetQuackBehavior(IQuackBehavior quackBehavior)
{
QuackBehavior = quackBehavior;
}
#endregion
public void Display()
{
Console.WriteLine("I'm a real Mallard duck");
}
}
// 行爲接口的具體實現
public class MallerdDuckQuack : IQuackBehavior
{
public void Quack()
{
Console.WriteLine("I'm a mallard duck. Ga ga ...");
}
}
// 行爲接口的具體實現
public class FlyWithWind : IFlyBehavior
{
public void Fly()
{
Console.WriteLine("I'm a mallard duck. I'm flying with the wind.");
}
}
#endregion
#region 以下是不變的部分
public class Duck
{
// 用接口作爲基類的字段
public IQuackBehavior QuackBehavior;
public IFlyBehavior FlyBehavior;
// 調用接口的方法
public void PerformQuack()
{
QuackBehavior.Quack();
}
// 調用接口的方法
public void PerformFly()
{
FlyBehavior.Fly();
}
}
// 行爲抽象爲接口
public interface IFlyBehavior
{
void Fly();
}
// 行爲抽象爲接口
public interface IQuackBehavior
{
void Quack();
}
#endregion
}