Head First 设计模式 01-策略模式
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,次模式让算法的变化独立于使用算法的客户。
如下类图所示,将 Duck 类的行为抽象为 Behavior 接口,然后在其子类 MallardDuck 中对 Behavior 属性指定其具体实现。
此种方式还有优点就是 Behavior 属性可以在运行时动态的改变,使系统的弹性更大。
设计原则
No.1
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
No.2
针对接口封装,而不是针对实现编程。
No.3
多用组合,少用继承。
示例代码
Duck
csharp
namespace StrategyPattern
{
public abstract class Duck
{
public FlyBehavior FlyBehavior { get; set; }
public QuackBehavior QuackBehavior { get; set; }
public Duck()
{
}
public void performFly()
{
FlyBehavior.Fly();
}
public void performQuack()
{
QuackBehavior.Quack();
}
public void Swim()
{
Console.WriteLine("All ducks float, even decoys!");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
FlyBehavior
csharp
namespace StrategyPattern
{
public interface FlyBehavior
{
void Fly();
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
FlyWithWings
csharp
namespace StrategyPattern
{
public class FlyWithWings : FlyBehavior
{
public void Fly()
{
Console.WriteLine("I'm flying!!");
}
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
QuackBehavior
csharp
namespace StrategyPattern
{
public interface QuackBehavior
{
void Quack();
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
Quack
csharp
namespace StrategyPattern
{
public class Quack : QuackBehavior
{
void QuackBehavior.Quack()
{
Console.WriteLine("Quack");
}
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
MallardDuck
csharp
namespace StrategyPattern
{
public class MallardDuck : Duck
{
public MallardDuck()
{
QuackBehavior = new Quack();
FlyBehavior = new FlyWithWings();
}
public void Display()
{
Console.WriteLine("I'm a real Mallard duck.");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Program
csharp
namespace StrategyPattern
{
class Program
{
static void Main(string[] args)
{
Duck mallard = new MallardDuck();
mallard.performQuack(); // print Quack
mallard.performFly(); // print I'm flying!!
Console.ReadLine();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13