软件工程 设计模式学习之策略模式Strategy

技术交流,DH讲解.

还是之前的文章,从之前博客转过来.

当我们有一个类如类A有一个方法C,但是这个C方法却被很多情况影响,
那么我们该怎么设计才能让代码更加容易理解呢?
其实我们前面讲的简单工厂模式也能实现.但是现在想说一下策略模式了.
我们来看一个UML图:软件设计师上半年和下半年考试里面都有这样一个题,给一个UML让你说这个UML是哪个模式?哈哈
image

我们能看到主类Context和Strategy是聚合关系吧,这里可以是一个属性 或者是一个成员变量.
而Strategy却有多个具体的实现类.

用代码说话:

abstract class PHPBase{
    public abstract function DoIt();
} 

class Add extends PHPBase{
    public function DoIt() {
        echo('Add\n');
    }
}
class Sub extends PHPBase{
    public function DoIt() {
        echo('Sub\n');
    }
}
class PHPStrategy {
    public function test($a){
        $b=NULL;
        switch($a){
            case 0:
                $b=new Add();
                break;
            case 1:
                $b=new Sub();
                break;
        }
        $b->DoIt();
    }
}

是不是和工厂模式有点儿像?
    $a=new PHPStrategy();
    $a->test(0);
    $a->test(1);
看看结果呢?
Add\nSub\n
没有换行...哈哈郁闷.

接下来还是用C#的吧,反正这么多人用:

namespace Strategy_DesignPattern
{
    using System;

	
	abstract class Strategy 
	{
		abstract public void DoAlgorithm();
	}

	class FirstStrategy : Strategy 
	{
		override public void DoAlgorithm()
		{
			Console.WriteLine("In first strategy");			
		}
	}

	class SecondStrategy : Strategy 
	{
		override public void DoAlgorithm()
		{
			Console.WriteLine("In second strategy");			
		}
	}

	class Context 
	{
		Strategy s;
		public Context(Strategy strat)
		{
			s = strat;			
		}

		public void DoWork()
		{
			// 这里
		}

		public void DoStrategyWork()
		{
			s.DoAlgorithm();
		}
	}

    public class Client
    {
        public static int Main(string[] args)
		{	
			FirstStrategy firstStrategy = new FirstStrategy();
			Context c = new Context(firstStrategy);
			c.DoWork();
			c.DoStrategyWork();

            return 0;
        }
    }
}

最后肯定是Delphi登场了,这里我就不写了,直接用Delphi创建出来的.

  IStrategy = Interface;

  TContext = Class
  Strict Private
  Var
    /// <link>aggregation</link>
    FStrategy: IStrategy;
  Public
    Constructor Create(AStrategy: IStrategy);
    Procedure ContextRequest;
  End;

  IStrategy = Interface
    Procedure Sample;
  End;

  TConcreteStrategy = Class(TInterfacedObject, IStrategy)
  Public
    Procedure Sample;
  End;

Implementation

{$R *.dfm}


Constructor TContext.Create(AStrategy: IStrategy);
Begin
  Inherited Create;
  FStrategy := AStrategy;
End;

Procedure TConcreteStrategy.Sample;
Begin
  { put your code for this particular strategy here }
End;

Procedure TContext.ContextRequest;
Begin
  FStrategy.Sample;
End;

我们的实际算法类只要实现IStrategy接口就可以了.

最后说下适用情况:

  • 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
  • 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。
  • 当这些变体实现为一个算法的类层次时[ H O 8 7 ] ,可以使用策略模式。
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
  • 一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。
  • 将相关的条件分支移入它们各自的S t r a t e g y 类中以代替这些条件语句。

    今天就到这里了,我是DH.

  • 原文地址:https://www.cnblogs.com/huangjacky/p/1625180.html