《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
}