zoukankan      html  css  js  c++  java
  • 软件工程 设计模式学习之策略模式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.

查看全文
  • 相关阅读:
    JS设计模式(11)中介者模式
    PHP实现微信模板消息发送给指定用户
    PHP浮点精度问题
    PHP微信红包生成算法的程序源码(用抛物线的模型实现)
    PHP队列的实现详细操作步骤
    PHP数组函数实现栈与队列的方法介绍(代码示例)
    Laravel 事务中使用悲观锁
    array_reduce — 用回调函数迭代地将数组简化为单一的值
    PHP上传文件和下载
    php导出xls,报错:文件格式和扩展名不匹配。该文件可能已损坏或不安全。除非你相信它的来源,否则不要打开它。
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1625180.html
  • Copyright © 2011-2022 走看看