似乎每当我使用命令模式时,它总是导致比我不使用它时更多的类.这似乎很自然,因为我们在不同的类中一起执行相关代码块.如果我没有完成10或12个Command子类,我可能会认为这个项目本来只会使用6或7个类,否则不会打扰我.对于通常的7级项目,有19个左右的课程似乎差错了.
真正困扰我的另一件事是测试所有这些Command子类是一件痛苦的事.在我接到最后几条命令之后,我感到迟钝,好像我移动速度慢,不再灵活.
这对你来说听起来很熟悉吗?我做错了吗?我只是觉得我在这个项目的后期失去了敏捷,而且我真的不知道如何以前几天的速度不断地实施和测试.
我有一个在数据库中排队的作业列表,我需要从数据库中读取并使用线程并行执行它们,我有一个命令类列表来执行每个所有实现公共接口(命令模式)的作业.但是当我从数据库中检索挂起的作业时,我需要为每个作业实例化正确的命令对象(在工厂类中)
ICommand command;
switch (jobCode)
{
case "A":
command = new CommandA();
break;
case "B":
command = new CommandB();
break;
case "C":
command = new CommandC();
break;
}
command.Execute();
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来创建正确的命令对象而不使用上面的大开关语句?或者是否还有其他模式来执行排队的作业?
解决方案:这样解决(基于所选答案).这将执行命令对象的延迟实例化.
public class CommandFactory
{
private readonly IDictionary<string, Func<ICommand>> _commands;
public CommandFactory()
{
_commands = new Dictionary<string, Func<ICommand>>
{
{"A", () => new CommandA()},
{"B", () => new CommandB()},
{"C", () => new CommandC()}
};
}
public ICommand GetCommand(string jobKey)
{
Func<ICommand> command;
_commands.TryGetValue(jobKey.ToUpper(), out command);
return command();
}
} …Run Code Online (Sandbox Code Playgroud) 是否有一个库已经提供了Java中命令模式所需的接口?
例如:
public interface Func1<T,R> { public R execute(T input); }
public interface Func2<T1,T2,R> { public R execute(T1 input1, T2 input2); }
public interface Predicate1<T> { public boolean execute(T input); }
....
Run Code Online (Sandbox Code Playgroud)
谢谢.
我有一种情况,我正在讨论如何构建我的控制器.
考虑以下控制器:
public class FileSharingController : Controller
{
private readonly ICommandBus commandBus;
public FileSharingController(ICommandBus commandBus)
{
this.commandBus = commandBus;
}
[HttpPost]
public ActionResult PrepareMetadata(int blocksCount, string fileName, long fileSize)
{
...
}
[HttpPost]
public ActionResult ClearFileMetadata(string fileName){
...
}
[HttpPost] [ValidateInput(false)] //$.ajax({ data: html5FormDataFileChunk , processData: false ... })
public ActionResult UploadBlock(string fileName, int blockId){
var fileUploadCommand = (FileUploadCommand)ExtractFromSessionData(fileName);
var result = commandBus.Submit(fileUploadCommand);
...
}
public ActionResult CommitFileUploads(string[] filesToCommit){
var commitFileUploadCommand = (CommitFileUploadCommand)ExtractFromSessionData(fileName);
var result = commandBus.Submit(commitFileUploadCommand );
...
} …Run Code Online (Sandbox Code Playgroud) 我最近遇到了很多问题,因为包中似乎有一个错误MassTransit.UnityIntegration,主要是因为注册名称没有被考虑.
例如,如果我像这样注册我的类:
var container = new UnityContainer()
.RegisterType<Consumes<Command1>.All, Handler1>("Handler1")
.RegisterType<Consumes<Command1>.All, Handler3>("Handler3");
Run Code Online (Sandbox Code Playgroud)
几行之后,我使用LoadFrom扩展方法来获取容器中的注册使用者,如下所示:
IServiceBus massTransitBus = ServiceBusFactory.New(_sbc =>
{
_sbc.UseBinarySerializer();
_sbc.UseControlBus();
_sbc.ReceiveFrom("msmq://localhost/MyQueue");
_sbc.UseMsmq(_x =>
{
_x.UseSubscriptionService("msmq://localhost/mt_subscriptions");
_x.VerifyMsmqConfiguration();
});
_sbc.Subscribe(_s => _s.LoadFrom(container));
});
Run Code Online (Sandbox Code Playgroud)
当相关消息到达总线时,我的处理程序永远不会被调用.
在思考了一段时间之后,我决定看一下实现,并且很清楚为什么会发生这种情况:
这是方法中的主要代码LoadFrom:
public static void LoadFrom(this SubscriptionBusServiceConfigurator configurator, IUnityContainer container)
{
IList<Type> concreteTypes = FindTypes<IConsumer>(container, x => !x.Implements<ISaga>());
if (concreteTypes.Count > 0)
{
var consumerConfigurator = new UnityConsumerFactoryConfigurator(configurator, container);
foreach (Type concreteType in concreteTypes)
consumerConfigurator.ConfigureConsumer(concreteType);
}
...
}
Run Code Online (Sandbox Code Playgroud)
请注意,它只查找类型,并且不会向前传递任何名称信息.这是FindTypes<T>实施:
static …Run Code Online (Sandbox Code Playgroud) 我有控制器根据命令名执行一些命令,取自url.重点是不使用if和switch子句.据我所知,只有两种方法可以做到 - 1)命令模式2)反射.
//Command pattern
class Controller{
private HashMap<String,Command> commands;
public void executeCommand(String commandName){
commands.get(commandName).execute();
}
...
}
//reflection
class Controller{
public void readCommand(){
....
}
public void executeCommand(String commandName){
this.getClass().getMethod(commandName+"Command").invoke(this);
}
...
}
Run Code Online (Sandbox Code Playgroud)
所以问题:
为什么我需要使用责任链,如果我可以将所有命令加载到某个容器中并且只是逐个执行命令.这将成为连续处理请求的链.BTW我觉得它比CoR更好,因为你可以删除一些特定的命令或在运行时替换另一个命令,而对于CoR,你需要创建另一个链来改变链中的某些东西,因为你无法访问链中的元素.除第一个元素外的链.(实际上,它是一个单一的链表.)
containers design-patterns command-pattern chain-of-responsibility
我正在构建一个web api应用程序.我想知道调用用例层的最佳方法是什么.一个选项是使用uncle bob的交互者,如下所述:Interactors 另一种选择是使用命令模式,如下所述:命令模式
该解决方案之间至少从我了解的主要区别是,在相互作用蛋白溶液中的控制器不知道处理程序,它只是发送一个请求,一些交互件会做的工作,而在命令选项控制器需要调用命令.
您认为更好的解决方案是什么?
architecture command-pattern asp.net-web-api asp.net-web-api2
好吧,这有点愚蠢。我正在尝试围绕 MVC 和命令模式的使用。这些问题主要涉及在哪里放置代码。
在 MVC 模式中,命令在哪里实例化?它们是由控制器创建的,还是完全包含在模型中,或者两者都不是。
顺便说一句,如果不需要撤消/重做,应该使用命令模式。
问候
我必须在EXT.NET中实现进度条.我在处理事务时有一个"处理"命令.我必须跟踪失败和成功的交易和交易总数.例如"共有60笔交易.12笔交易失败,48笔交易成功".
我现在的问题是,我可以使用命令模式来实现这个吗?我不是要求代码,但我想知道它是否有意义.
这样做的原因是我必须实现一些设计模式以进行分配.
(http://en.wikipedia.org/wiki/Command_pattern其中一个应用程序是进度条)
PS:
如果有人有一个使用命令模式实现的进度条的示例,请随意发布:P
command-pattern ×10
c# ×2
java ×2
.net ×1
agile ×1
architecture ×1
asp.net ×1
containers ×1
esb ×1
ext.net ×1
masstransit ×1
progress-bar ×1
reflection ×1
testing ×1
web-services ×1