我一直在研究策略模式实现示例,在我看来它们与c#delegates非常相似.我看到的唯一区别是策略模式实现不需要显式声明委托.
但除此之外,它们似乎都指向需要特定签名的函数,它们都可以用于确定在运行时执行的内容.
我错过了一个更明显的区别吗?
我想一个相关的问题是,如果它们相似,那么使用一个优于另一个的优势是什么?
我基本上试图实现一个策略模式,但我想将不同的参数传递给"接口"实现(继承自同一个对象)并且不知道这是否可行.也许我选择了错误的模式,我得到类似的错误
'StrategyA'没有实现继承的抽象成员'void DoSomething(BaseObject)'
使用以下代码:
abstract class Strategy
{
public abstract void DoSomething(BaseObject object);
}
class StrategyA : Strategy
{
public override void DoSomething(ObjectA objectA)
{
// . . .
}
}
class StrategyB : Strategy
{
public override void DoSomething(ObjectB objectB)
{
// . . .
}
}
abstract class BaseObject
{
}
class ObjectA : BaseObject
{
// add to BaseObject
}
class ObjectB : BaseObject
{
// add to BaseObject
}
class Context
{
private Strategy _strategy;
// …
Run Code Online (Sandbox Code Playgroud) c# inheritance abstract-class design-patterns strategy-pattern
我正在看这个,http://en.wikipedia.org/wiki/Strategy_pattern,我理解战略模式的概念,但有人可以解释一下C#的例子.
我真的不知道在Context类中定义"策略"的方式和原因,为什么它Func<T, T, T>
只是两个参数传递给例如8,9?
static void Main(string[] args)
{
var context = new Context<int>();
// Delegate
var concreteStrategy1 = new Func<int, int, int>(PerformLogicalBitwiseOr);
// Anonymous Delegate
var concreteStrategy2 = new Func<int, int, int>(
delegate(int op1, int op2)
{
return op1 & op2;
});
// Lambda Expressions
var concreteStrategy3 = new Func<int, int, int>((op1, op2) => op1 >> op2);
var concreteStrategy4 = new Func<int, int, int>((op1, op2) => op1 << op2);
context.Strategy = concreteStrategy1;
var result1 = …
Run Code Online (Sandbox Code Playgroud) 我正在使用php 5.2.6.我有一个策略模式,策略有一个静态方法.在实际实现其中一个策略的类中,它获取要实例化的策略类的名称.但是,我想在实例化之前调用其中一个静态方法,如下所示:
$strNameOfStrategyClass::staticMethod();
Run Code Online (Sandbox Code Playgroud)
但它给了T_PAAMAYIM_NEKUDOTAYIM
.
$> cat test.php
<?
interface strategyInterface {
public function execute();
public function getLog();
public static function getFormatString();
}
class strategyA implements strategyInterface {
public function execute() {}
public function getLog() {}
public static function getFormatString() {}
}
class strategyB implements strategyInterface {
public function execute() {}
public function getLog() {}
public static function getFormatString() {}
}
class implementation {
public function __construct( strategyInterface $strategy ) {
$strFormat = $strategy::getFormatString();
}
}
$objImplementation = & …
Run Code Online (Sandbox Code Playgroud) 我需要处理从服务返回的记录列表.
然而,记录的处理算法完全基于记录上的某个字段而改变.
为了实现这一点,我已经定义了一个只有一个方法的IProcessor接口:
public interface IProcessor
{
ICollection<OutputEntity> Process(ICollection<InputEntity>> entities);
}
Run Code Online (Sandbox Code Playgroud)
我有两种IProcessor
不同类型处理的具体实现.
问题是我需要同时使用所有实现IProcessor
..所以我如何注入IProcessor
我的Engine类来驱动整个事情:
public class Engine
{
public void ProcessRecords(IService service)
{
var records = service.GetRecords();
var type1Records = records.Where(x => x.SomeField== "Type1").ToList();
var type2Records = records.Where(x => x.SomeField== "Type2").ToList();
IProcessor processor1 = new Type1Processor();
processor.Process(type1Records);
IProcessor processor2 = new Type2Processor();
processor.Process(type2Records);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我目前正在做的事情......它看起来并不好看.
关于如何改进这种设计的任何想法......或许使用IoC?
我正在寻找抽象一个辅助方法。该方法需要能够接收一个对象,根据对象的类型对其执行操作,并返回一个值。这样做会更好吗:
interface ICanDo
{
string DoSomething();
}
string DoThings(ICanDo mything)
{
return mything.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
或者最好做这样的事情:
interface IStrategy
{
string DoSomething(object o);
}
string DoThings(object mything, IStrategy strategy)
{
return strategy.DoSomething(mything);
}
Run Code Online (Sandbox Code Playgroud)
后者是否甚至使用策略模式,因为该策略没有内置到类中?
有没有更好的方法来做到这一点我没有想到?将策略构建到类中,为任何需要运行 DoThings 的类使用包装器会更好吗?
抱歉——我对这种模式很陌生,并试图弄清楚在哪里以及如何最好地使用它。
这就是我最终整理出来的。我不确定这是否遵循良好的开发原则。
class IndexWrapper
{
public interface IDocumentable
{
Document BuildDocument();
}
public interface IDocumentBuilder
{
Type SupportedType { get; }
Document BuildDocument(object o);
}
public class StringDocumentBuilder : IDocumentBuilder
{
public Type SupportedType { get { return typeof(string); } }
public Document BuildDocument(object o) …
Run Code Online (Sandbox Code Playgroud) 我正在重新设计一个库,我对目前的设计模式不满意.这个问题涉及战略模式与州Monad一起使用
我有一个Filter
.在它的基本实现中,它所做的就是获取一些类型的数据源'd
并更新自身,生成一个新的自身更新副本.
[<AbstractClass>]
type Filter<'d, 'F> (state: 'F) =
member val StateVariable = state with get
abstract member Update: 'd -> Filter<'d, 'F>
Run Code Online (Sandbox Code Playgroud)
我有一个ISignalGenerator
,它采用过滤器,环境数据并处理它以生成一种Signal
类型'S
.
type ISignalGenerator<'d, 'F, 'S> =
abstract member GenerateSignal: 'd -> Filter<'d,'F> -> 'S
Run Code Online (Sandbox Code Playgroud)
这SignalGenerator
是一个策略模式对象.在SignalGenerator
实现中,库用户安装将使用和组合以生成的函数Signal
.
我可以将我的代码包装在状态monad中.与一些环境变量(数据馈送)一起,状态monad将携带'Filter'作为状态.SignalGenerator
然后将通过状态monad获取状态更新(类型的数据馈送'd
和Filter
)
我的设计问题是我想将SignalGenerator
类型从工作流程的开发中分离出来,即我想避免将状态monad嵌套在其中SignalGenerator
.是否有功能设计模式来实现这一目标?
编辑
根据Tomas的评论,我参与了一个玩具模型.具有策略类的选择基于将许多功能组合在一起的需要.
/////////////////////////////////////////////////////////////////////////////////////
// Definition of the state …
Run Code Online (Sandbox Code Playgroud) 我已经阅读过以前的堆栈交换,用Java替换条件逻辑,例如带有状态/策略模式的IF/ELSE,但我不确定我的情况是否适合替换.以下是我看到的结果 - Java中的if语句的长列表以及将许多'if else'语句转换为更干净的方法
我本质上是在编写一个文件下载管理器,这些是我的IF/ELSE结构:
基本上我理解你将这四个条件作为哈希映射中的键,然后值是需要发出的"命令".但是我相信你仍然需要一个If/Else来决定在作为输入给出的键上调用什么动作.所以我没有看到好处.有人可以解释一下吗?
对于项目,我们有一个Controller/Service/DAO架构.我们实现了对不同提供者API的调用,因此我们在每个控制器类中都得到了一些这样的样板代码:
enum {
PARTNER_A, PARTNER_B, PARTNER_C
}
public class MyController {
@Resource PartnerASearchService partnerASearchService;
@Resource PartnerBSearchService partnerBSearchService;
@Resource PartnerCSearchService partnerCSearchService;
public search(InputForm form) {
switch(form.getPartnerName()) {
case PARTNER_A: partnerASearchService.search();
break;
case PARTNER_B: partnerBSearchService.search();
break;
case PARTNER_C: partnerCSearchService.search();
break;
}
}
public otherMethod(InputForm form) {
switch(form.getProvider()) {
case PARTNER_A: partnerAOtherService.otherMethod();
break;
case PARTNER_B: partnerBOtherService.otherMethod();
break;
case PARTNER_C: partnerCOtherService.otherMethod();
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用哪种设计模式来摆脱每个控制器中的这个开关?我希望代码类似于下面的代码:
public class MyController {
@Resource ServiceStrategy serviceStrategy;
public search(InputForm form){
serviceStrategy.search(form.getPartnerName())
// or
serviceStrategy.invoke(SEARCH, form.getPartnerName())
}
public otherMethod(InputForm …
Run Code Online (Sandbox Code Playgroud) 我有一个类层次结构,如:
|-> Square
AbstractShape -+-> Circle
|-> Triangle
Run Code Online (Sandbox Code Playgroud)
现在,我想实现策略模式并创建一个存储在字符串中的类对象.在PHP中我会使用:
$type = 'Square';
$obj = new $type();
Run Code Online (Sandbox Code Playgroud)
Node.js中有等价物吗?
strategy-pattern ×10
c# ×4
java ×2
c#-4.0 ×1
delegates ×1
f# ×1
if-statement ×1
inheritance ×1
javascript ×1
node.js ×1
php ×1
php-5.2 ×1
state ×1
state-monad ×1