我曾与某人就战略模式的真正斗争而斗争,我需要专家来解决这个问题.
我们都同意策略模式允许在运行时交换类的内容(例如,行为),同时保持相同的接口.然而,她的论点是"为了[算法]成为一种策略,你必须得到相同的结果".我的论点是,交换"算法"或类的逻辑可能意味着被覆盖的操作的结果是不同的,但它仍然符合策略模式的目的,意图(和分类).
她的代码示例带有注释:
根据您的定义,类的任何子类都是策略.它们具有相同的方法定义(签名),因此可以互换.
Interface Strategy
{
DoArithmatic(int[] a)
}
Class A : Strategy
public int DoArithmatic(int[]a)
{
int temp = 0;
for(int i =0; i< a.length; i++)
temp += a[i]
}
Class B : Strategy
public int DoArithmaticB(int[]a)
{
int temp = 0;
for(int i =a.length -1; i>-1; i--)
temp += a[i]
}
Class C : Strategy
public int DoArithmatic(int[]a)
{
int temp = 0;
for(int i =0; i< a.length; i++)
temp -= a;
}
int[] a = { …Run Code Online (Sandbox Code Playgroud) 更新:增加了一个问题(问题#4).
大家好,
我正在构建自己的自定义电子邮件实用程序.现在,为了遵守单一责任原则,我想拥有以下类:MailerSender,MailProvider和EmailObject.MailSender更像是一个代表,请在下面查看:
public class MailSender {
private IMailProvider mailProvider;
public void setMailProvider (IMailProvider provider) {
this.mailProvider = provider;
}
// option to set it up during construction
public MailSender (IMailProvider provider) {
this.mailProvider = provider;
}
public void sendEmail(EmailObject obj) {
if(mailProvider == null)
throw new RuntimeException("Need a mail provider to send email.");
try {
mailProvider.send(obj);
} catch (Exception e) {
// do something here
}
}
}
Run Code Online (Sandbox Code Playgroud)
MailSender需要一个IMailProvider电子邮件提供商来完成发送电子邮件的工作.在下面找到它:
public interface IMailProvider {
public void sendEmail(EmailObject obj);
} …Run Code Online (Sandbox Code Playgroud) 我有一个课程需要使用策略设计模式.在运行时,我需要切换不同的算法,以查看对应用程序性能的影响.
有问题的类目前在构造函数中有四个参数,每个参数代表一个算法.
如何使用Ninject(或通用方法)仍然可以使用IOC但使用策略模式?
目前的限制是我的内核(容器)知道每个算法接口,但只能绑定到一个具体的类.我现在可以看到的唯一方法是在构造中传递所有八种算法,但是使用不同的接口,但这似乎完全是不必要的.如果我没有使用IOC容器,我不会这样做,所以必须有一些解决方法.
代码示例:
class MyModule : NinjectModule
{
public override void Load()
{
Bind<Person>().ToSelf();
Bind<IAlgorithm>().To<TestAlgorithm>();
Bind<IAlgorithm>().To<ProductionAlgorithm>();
}
}
Run Code Online (Sandbox Code Playgroud)
人需要使用这两种算法,以便我可以在运行时切换.但只有TestAlgorithm被绑定,因为它是容器中的第一个.
正如Observer模式的命名约定(或者更确切地说,C#等语言中的事件的命名约定)使用事件/处理程序传递EventArgs等,是否有用于轻松突出代码中其他模式的命名约定?
编辑:我原本想问一下策略模式,但认为了解常见模式可能存在的任何其他约定会很有帮助.
我在java中有以下if-else分支.
if (str.equals("a")) { A;}
else if (str.equals("b")) { B;}
else if (str.equals("c")) { C;}
else if (str.length == 5) { D;}
else { E;}
Run Code Online (Sandbox Code Playgroud)
如何将此代码修改为策略模式?
似乎需要像下面这样的类型无处不在,以至于它应该已经内置到Java中:
public interface Executer<T> {
void execute(T object);
}
Run Code Online (Sandbox Code Playgroud)
然后它可以在其他类中使用,例如在一个对象上调用一堆执行器的简单示例.
class Handler<T> implements Executer<T> {
List<Executer<T>> executerList;
Handler(List<Executer<T>> executer) {
this.executerList = executer;
}
void execute(T t) {
for (Executer<T> executer : this.executerList) {
executer.execute(t);
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有内置类型等效或公共库等价?这个概念有名字吗?
我已经在rdlc报告中编写了一种处理多个子报告的技术,但是由于我试图使其具有通用性和可重复性,因此我不得不采用模型并针对每种情况稍微调整一下.
例如,如果我定义一个抽象接口,就像这样,我只需根据需要将其从winform剪切并粘贴到winform:
abstract class ISolutionStrategy
{
public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
}
Run Code Online (Sandbox Code Playgroud)
首先,我希望能够通过包含has-a对象将其带入每种形式.我还想封装委托处理调度的行为,并使处理方法也"通用".
因此,设计要求是:
目标是制作一个可以独立测试并且坚固耐用的物体,也不必剪切和粘贴滚轮,并为每个新的winform做一堆手动调整.
在我看来,有人找到了比我现在更好的设计.
创建一个可以包含在winform中的对象,以处理多个子报表处理
到目前为止,我在本地表单加载事件中有一个委托:
this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
Run Code Online (Sandbox Code Playgroud)
它由*LocalReport_SubreportProcessing*方法中的switch语句处理.
该方法的主体包含一个switch语句:
void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
{
String commonSubreportKey = _commonSubreportKey;
switch (e.ReportPath)
{
case "rptSubAlternateParts":
runSubAlternatePart(e, commonSubreportKey, new GetAlternateParts());
break;
case "rptSubGetAssemblies":
runSubFailurePart(e, commonSubreportKey, new GetAssemblies());
break;
case "rptSubGetAssemblies":
runSubGetGetEndItemLRMFailureInfo(e, commonSubreportKey, new GetEndItemLRMFailureInfo());
break;
case "rptSubGetAssemblies":
runSubGetSubAssemblies(e, commonSubreportKey, new GetSubAssemblies());
break;
default:
break;
}
Run Code Online (Sandbox Code Playgroud)
在旁边:在我看来,与我考虑的替代方案相比,这种转换大多是人类可读的.我考虑使用带有报告名称的哈希作为键,并将函数调用数据作为值.但是,我真的不知道怎么做,我认为其他人更难理解.
之后,调用一个函数,该函数重新排列switch语句中从函数调用传递的信息:
private static void …Run Code Online (Sandbox Code Playgroud) 这是策略界面的外观
public interface Strategy
{
public void doStuff(Object o);
}
Run Code Online (Sandbox Code Playgroud)
这是一个可能的实现
public class StrategyImpl implements Strategy
{
@Override
public void doStuff(Object o)
{
//Do things with o
}
}
Run Code Online (Sandbox Code Playgroud)
现在,使用StrategyImpl实现可能有数百个对象。应该为所有这数百个对象创建一个StrategyImpl的新实例,还是有更好的方法?
我在这里已经读过,不应使用单例来节省内存,但是似乎没有必要创建数百个相同的实例。也许最好的解决方案不是单例,而是某种方式。
我应该如何制定策略?我是否应该不理会这些类型的问题?
在C#中,我有以下代码:
public class SomeKindaWorker
{
public double Work(Strategy strat)
{
int i = 4;
// some code ...
var s = strat.Step1(i);
// some more code ...
var d = strat.Step2(s);
// yet more code ...
return d;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一段代码,可以通过使用提供的策略对象来填充部分实现来完成某种工作.注意:一般来说,策略对象不包含状态; 它们只是多态地提供各个步骤的实现.
策略类如下所示:
public abstract class Strategy
{
public abstract string Step1(int i);
public abstract double Step2(string s);
}
public class StrategyA : Strategy
{
public override string Step1(int i) { return "whatever"; }
public override double Step2(string …Run Code Online (Sandbox Code Playgroud) 为什么策略设计模式和适配器相互关联?它告诉我,适配器操纵某些方法的结果来满足另一个人的输入需求.该策略可以预防行为.
strategy-pattern ×10
java ×4
c# ×2
oop ×2
adapter ×1
delegates ×1
f# ×1
functor ×1
if-statement ×1
ninject ×1
rdlc ×1
singleton ×1
subreports ×1