这个模式我的理解是在Context角色调用简单工厂返回父类的对象.2.将对象传到抽象方法中实现.
这个模式很强大.与客户端完全隔离.适用地方和简单方法一致.(使用于多变的场合.比如说我遇到的一个客户要的出货资料。条件如下
1.A/B包装+A/B产品测试(这个下面两个的和)
2.A产品包装+A产品测试
3.B产品包装+B产品测试
……测试出货等等.传一个工单到Context然后调用抽象方法.)
好像就是在简单工厂上再次封装.
这个模式涉及到三个角色:
- 环境(Context)角色:持有一个Strategy类的引用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
抽象策略(Strategy)
public abstract class BaseStrategy
{
public abstract bool Scan1(out string err);
public abstract bool Scan2(out string err);
public abstract bool Scan3(out string err);
public abstract bool Scan4(out string err);
}//定义抽象类,用接口也可以
上下文环境(Context)
public class Context
{
private BaseStrategy _strategy = null;
public Context(BaseStrategy strategy)
{
_strategy = strategy;
}
public bool Scan1(out string err)
{
return _strategy.Scan1(out err);
}
public bool Scan2(out string err)
{
return _strategy.Scan2(out err);
}
public bool Scan3(out string err)
{
return _strategy.Scan3(out err);
}
public bool Scan4(out string err)
{
return _strategy.Scan4(out err);
}
}//上下文
具体策略
public override bool Scan1(out string err)
{
err = "";
FunctionTest.txt_sn1.Enabled = false;
//第一个条码
SnRange snRange = new SnRange()
{
CheckJobNum = TestInfo.JobParam.CheckJob1,
Start = TestInfo.JobParam.Sn1Start,
Oui = TestInfo.JobParam.Sn1OuI,
End = TestInfo.JobParam.Sn1End
};
TestBase decorator = new Function.PublicFun.CheckProcess(FunctionTest.txt_sn1.Text) { FunctionTest = FunctionTest, TestInfo = TestInfo, SnRange = snRange };
decorator = new BaseDecorator(decorator);
decorator = new Function.PublicFun.CheckJobQuantity(decorator) //确认工单数量是否超出
{ FunctionTest = FunctionTest, TestInfo = TestInfo, CheckOrShowP = Function.PublicFun.CheckJobQuantity.CheckOrShow.Check };
if (TestInfo.JobParam.BoxLabPath != "")
{
decorator = new Function.Pair.PrintLab(decorator)
{ FunctionTest = FunctionTest, TestInfo = TestInfo, IsPrint = true, BoxSn = FunctionTest.txt_sn1.Text };
}
decorator = new Function.PublicFun.SaveDataBase(decorator) { FunctionTest = FunctionTest, TestInfo = TestInfo ,Sn= FunctionTest.txt_sn1.Text };
decorator = new Function.PublicFun.CheckJobQuantity(decorator) { FunctionTest = FunctionTest, TestInfo = TestInfo, CheckOrShowP = Function.PublicFun.CheckJobQuantity.CheckOrShow.Show };
if (!decorator.Test(out err))
{
FunctionTest.lb_message.Text = err;
FunctionTest.lb_message.ForeColor = System.Drawing.Color.Red;
FunctionTest.txt_sn1.Enabled = true;
FunctionTest.txt_sn1.SelectAll();
FunctionTest.txt_sn1.Focus();
return false;
}
FunctionTest.lb_message.Text = FunctionTest.txt_sn1.Text + @"->PASS";
FunctionTest.lb_message.ForeColor = System.Drawing.Color.Green;
FunctionTest.txt_sn1.Enabled = true;
FunctionTest.txt_sn1.Text = "";
FunctionTest.txt_sn1.Focus();
return true;
}
public override bool Scan2(out string err)
{
throw new NotImplementedException();
}
public override bool Scan3(out string err)
{
throw new NotImplementedException();
}
public override bool Scan4(out string err)
{
throw new NotImplementedException();
}
在使用时我搞了一个简单工厂,如果逻辑简单可以不使用.
public BaseStrategy CreateStrategy()
{
//按客户区分,后面在写
BaseStrategy strategy = null;
if (TestInfo.Position.Equals("Scan"))
{
strategy = new StrategyScan() { TestInfo = TestInfo, FunctionTest = FunctionTest };
}
else if (TestInfo.Position.Equals("Pair"))
{
strategy = new StrategyPair() { TestInfo = TestInfo, FunctionTest = FunctionTest };
}
else if (TestInfo.Position.Equals("Pack"))
{
strategy = new StrategyPack() { TestInfo = TestInfo, FunctionTest = FunctionTest };
}
else
{
FrmDialog.ShowDialog(null, "没有发现对应的站位设定", System.Drawing.Color.Red);
}
return strategy;
}
下面是调用
BaseStrategy strategy = new TestClass.StrategyPattern.SimpleFactory(TestInfo, this).CreateStrategy();
_contextStrategy = new TestClass.StrategyPattern.Context(strategy);
//声明对象,TestInfo里面有对应的站位.CreateStrategy方法就知道使用哪一个类.
// 使用
_contextStrategy.Scan1(out string err);