定义:它定义了算法家族,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户
用途:应对时常变化的算法
案例:车辆过磅系统。
概述:将地磅通过串口连接到电脑,读取串口信息,其中可能变化的部分是:不同的地磅读取的数据格式往往不是不一样的(此例中以火车过磅和汽车过磅说明),为了读取真正的数据,必须定义一个分析字符串的算法,这个算法会因为不同的地磅而不同
用策略模式解决问题:将可能变化的多种分析字符串的算法分装起来,提供给客户端代码一个统一的接口。使得替换算法时不会影响到客户端的代码(不需修改)
类图:
- 定义一个接口:IGetPortData,接口中定义一方法:int Getdata(string originalString),此方法用来分析读串口得到字符串
- 汽车过磅类GetTruckScaleData和火车过磅类GetTrainScaleData继承上述接口并分别实现了方法Getdata(string origianlString)。客户代码类中包含一个IGetPortData的引用,可以动态的指向GetTruckScaleData或GetTrainSclaeData而无需修改代码
代码实例:(为了简单而写在了一个了文件里了。:-))
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO.Ports;
namespace ServalPort
{
class Program
{
static void Main(string[] args)
{
CustomerCode customerCode = new CustomerCode();
customerCode.getWeight();
}
}
/// <summary>
/// customer code
/// </summary>
public class CustomerCode
{
private IGetPortData _getPortData;
private System.IO.Ports.SerialPort _serialPort;
public CustomerCode(string portName,int baudrate,int dataBits,SerialPort stopBits)
{
this._serialPort.PortName = portName;
this._serialPort.BaudRate = baudrate;
this._serialPort.StopBits = stopBits;
this._serialPort.DataBits = dataBits;
this._getPortData = GetDataFactory.CreateInstance();
}
public int getWeight()
{
if(!this._serialPort.IsOpen)
{
this._serialPort.Open();
}
string originalString = this._serialPort.ReadLine();
int weight = this._getPortData.GetData(originalString);
}
}
/// <summary>
/// 获取重量的接口
/// </summary>
public interface IGetPortData
{
int GetData(string originalString);
}
/// <summary>
/// 汽车
/// </summary>
public class GetTruckScaleData : IGetPortData
{
public int GetData(string originalString)
{
return Convert.ToInt32(originalString.Substring(2, 3));//this is a test
}
}
/// <summary>
/// 火车
/// </summary>
public class GetTrainScaleData : IGetPortData
{
public int GetData(string originalString)
{
return Convert.ToInt32(originalString) + 2;//this is a test
}
}
public class GetDataFactory
{
public static IGetPortData CreateInstance()
{
//从配置文件中读取
string _assemblyRef=getFefFromFile();
string _type=getTypeFromFile();
return (IGetPortData)Assembly.Load(_AppDomain).CreateInstance(_type);
}
}
}
总结:只要修改配置文件(实例里没有具体设置。。。:-)),通过反射得到想要的算法。如果要增加一种新的地磅,只需一定一个实现了IGetWeightData的类,写好GetData()方法。修改配置文件(配置文件中保存类名)即可,无需修改客户端代码。