设计模式(20)策略模式

模式介绍

策略设计模式定义了一系列算法,然后通过将每个算法封装为对象使它们可互换。 因此,算法的实际操作可以基于其他输入而变化,例如哪个客户端正在使用它。

这种模式的基本思想是,如果我们将行为封装为对象,那么我们就可以选择使用哪个对象,从而根据一些外部输入或状态来实现哪些行为。我们进一步允许实现许多不同的行为,而无需创建巨大的if / then或switch语句。

示例

想象一下,我们有N中办法吃肉,烤炸煎等等。在面向对象的思想中,每一种方式都是一个类。

抽象的cook策略:

/// <summary>
/// The Strategy abstract class, which defines an interface common to all supported strategy algorithms.
/// </summary>
abstract class CookStrategy
{
    public abstract void Cook(string food);
}

具体的策略:

/// <summary>
/// A Concrete Strategy class
/// </summary>
class Grilling : CookStrategy
{
    public override void Cook(string food)
    {
        Console.WriteLine("\nCooking " + food + " by grilling it.");
    }
}

/// <summary>
/// A Concrete Strategy class
/// </summary>
class OvenBaking : CookStrategy
{
    public override void Cook(string food)
    {
        Console.WriteLine("\nCooking " + food + " by oven baking it.");
    }
}

/// <summary>
/// A Concrete Strategy class
/// </summary>
class DeepFrying : CookStrategy
{
    public override void Cook(string food)
    {
        Console.WriteLine("\nCooking " + food + " by deep frying it");
    }
}

上下文对象类,可选择不同的策略:

/// <summary>
/// The Context class, which maintains a reference to the chosen Strategy.
/// </summary>
class CookingMethod
{
    private string Food;
    private CookStrategy _cookStrategy;

    public void SetCookStrategy(CookStrategy cookStrategy)
    {
        this._cookStrategy = cookStrategy;
    }

    public void SetFood(string name)
    {
        Food = name;
    }

    public void Cook()
    {
        _cookStrategy.Cook(Food);
        Console.WriteLine();
    }
}

客户端调用:

static void Main(string[] args)
{
    CookingMethod cookMethod = new CookingMethod();

    Console.WriteLine("What food would you like to cook?");
    var food = Console.ReadLine();
    cookMethod.SetFood(food);

    Console.WriteLine("What cooking strategy would you like to use (1-3)?");
    int input = int.Parse(Console.ReadKey().KeyChar.ToString());
            
    switch(input)
    {
        case 1:
            cookMethod.SetCookStrategy(new Grilling());
            cookMethod.Cook();
            break;

        case 2:
            cookMethod.SetCookStrategy(new OvenBaking());
            cookMethod.Cook();
            break;

        case 3:
            cookMethod.SetCookStrategy(new DeepFrying());
            cookMethod.Cook();
            break;

        default:
            Console.WriteLine("Invalid Selection!");
            break;
    }
    Console.ReadKey();
}

总结

策略设计模式允许在不同情况下使用给定对象的不同行为。 这允许分别实现和测试许多不同的行为,因为每个行为将被封装为对象。
重构代码的时候,该模式可能会发挥作用。

源代码

https://github.com/exceptionnotfound/DesignPatterns/tree/master/Strategy

原文

https://www.exceptionnotfound.net/strategy-the-daily-design-pattern/

posted @ 2018-11-15 09:48  talentzemin  阅读(142)  评论(0编辑  收藏  举报