来说说(Strategy)策略模式

来源:互联网 发布:单类信息发布源码 编辑:程序博客网 时间:2024/06/06 18:05

1.什么是策略模式?为了解决什么问题?

实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
就像heard first 这本书最经典的例子,我们要实现一个鸭子的飞翔功能,他不同的鸭子叫声不一样,飞翔的样子不一样。例如我们出去玩。总要乘坐各种的交通工具,这是一个比较广泛的定义,底层怎么实现呢,我们可以坐火车,骑自行车,自驾游等?

2.我们应该这么办?

我们可以使算法完全独立于他的使用对象,然后在来进行计算,就是什么样的对象我不关心,我只关心这一系列的算法,例如,坐火车,坐飞机,自驾游,并且每个算法都完全独立,我们可以随便的扩张,而同时也不影响函数的调用。策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

3.那些情况下比较适合这些算法?

(1)一个类需要动态的用多种算法中的一种算法来动态的配置自己的实现。
(2) 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构
 (3) 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

4.我们来实现一个策略模式的小小例子。

我们以鸭子的飞行功能来创建一个策略模式,我们先来创建一个策略的算法基类fly
using System;using UnityEngine;/// <summary>/// 策略模式设计方案/// </summary>public  interface IFly{ void fly(GameObject gameObjects);}
在来创建一个垂直起飞的类型
/// <summary>/// 一种垂直起飞的实现/// </summary>public class UpFly : IFly{//一种飞行行为public void  fly(GameObject gameObjects){gameObjects.transform.Translate (new Vector3(0,1 * Time.deltaTime,0));}}

再来创建一个向右移动的类型
/// <summary>/// 向右边进行移动/// </summary>public class RightFly : IFly{//一种飞行行为public void fly(GameObject gameObjects){gameObjects.transform.Translate (new Vector3(1 * Time.deltaTime,0,0));}}

再来创建一个向左移动的类型
public class LeftFly : IFly{public void fly(GameObject gameObjects){gameObjects.transform.Translate  (new Vector3(-1 * Time.deltaTime,0,0));}}

我们在来创建一个鸭子的类。
using System;using UnityEngine;public class DuckTemple{IFly m_FlyBehaviour; //它的飞行行为GameObject m_GameObejcts; //显示类public DuckTemple (GameObject gameObejct){m_GameObejcts = gameObejct;m_FlyBehaviour = new UpFly ();//默认的飞行行为}public void Fly (){m_FlyBehaviour.fly (m_GameObejcts);}/// <summary>/// 动态的设置他的飞行行为/// </summary>/// <param name="fly">Fly.</param>public void setFlyBehaviour(IFly fly){m_FlyBehaviour = fly;}}
好了我们可以来进行测试了,在unity场景上创建一个plane,plane下面创建几个按钮,把test脚本添加到test上面。test如下
using System;using UnityEngine;using UnityEngine.UI;public class Test : MonoBehaviour{DuckTemple duk;public GameObject m_GameObejcts;void Start(){duk = new DuckTemple (m_GameObejcts);Button[]buttons =  gameObject.GetComponentsInChildren<Button> ();foreach(Button btn in buttons){btn.onClick.RemoveAllListeners ();btn.onClick.AddListener (()=> setButton(btn.gameObject));}}//我们来测试动态鸭子类void setButton(GameObject gameObjects){switch(gameObjects.name){case "Button_004":duk.Fly ();break;case "Button_003":duk.setFlyBehaviour (new RightFly());duk.Fly ();break;case "Button_002":duk.setFlyBehaviour (new LeftFly());duk.Fly ();break;default:break;}}}

好了,我们就完成了一个策略模式的设计,其实这种策略模式是利用了动态来动态的改变了函数指针的调用,从而来使用不同的算法。。。。。