我需要在我的应用程序中实现任务的概念。在我的项目中,任务是必须执行的操作,并由名称标识:每个任务还具有输入参数(类型和值)并产生一个或多个输出。
必须实现 Task 类,如何表达“有某种结果的操作”的概念?我可以将操作的名称存储在字符串属性中,但是如何表达此操作返回的类型?同样,当这些参数也可能是不同类型时,如何实现操作的输入参数列表?
目标是序列化 Task 对象并将其发送到另一个节点。接收者分析接收到的 Task 对象,读取操作名称并执行相应的函数。
例如,假设节点 A 和节点 B“具有”以下方法......
节点A的服务:
- double getAreaOfRectangle(double length, double width);
- double getAreaOfTriangle(double base, double height);
- double getAreaOfParallelogram(double base, double height).
Run Code Online (Sandbox Code Playgroud)
节点B的服务:
- double getAreaOfCircle(double radius);
- double getAreaOfTrapezoid(double base1, double base2, double height).
Run Code Online (Sandbox Code Playgroud)
如果节点 C 需要计算一个矩形的面积,它知道它必须联系节点 A 并通过指定操作(double areaOfRectangle)和输入(double width and double height)向节点 A 发送消息。同样,如果节点C需要计算一个圆的面积,它必须向节点B发送消息,指定操作和半径的长度。为了发送输入,因为它们可能是不同的类型(甚至是新的用户定义类型),我可以使用一个对象数组......
一些任务可能依赖于其他任务,即,因为输入参数可能至少有另一个任务的一个输出,所以我还需要实现一个任务的输出和另一个任务的输入之间的链接。
我应该如何继续定义类?
我知道纯函数式编程的目标之一是消除可变性,从而排除副作用.但是让我们面对现实吧,即使存在所有的函数式编程库,Java也不是一种函数式语言.事实上,似乎有些FP库知道并期待这一点.例如,在Functional Java中,有一个Effect类.在Jedi FP库中,有Command界面.这允许您 - 除其他外 - 将类型安全的命令模式应用于Iterable没有令人讨厌的for循环样板的元素.
Command<PhoneNumber> makeCall = new Command<PhoneNumber> {
public void execute(PhoneNumber p) { p.call(); }
}
List<PhoneNumber> phoneList = ...
FunctionalPrimitives.forEach( phoneList, makeCall );
Run Code Online (Sandbox Code Playgroud)
所以问题是,番石榴中有类似的东西吗?
在接受澄清后接受回复
我正在开发一个框架,它可以帮助解决大多数Java FP库中固有的"垂直问题",在某些情况下.所以,我不竟让如上图所示的代码示例:即明确宣布一个新的类实现的Command所有其垂直噪声过甜的烦躁,只需在声明之后立即应用它的目的.
我更多地考虑实际的命令模式,其中可能有几个可能的命令在其他地方声明,并且只有其中一个被传递到想要迭代应用它的代码中.此外,我的框架的目标是使创建功能接口对象(函数,谓词,命令,其他简单的lambda)更加惯用,而不是简单地将垂直问题移动到其他地方.我早就意识到这不在番石榴的范围内.但是由于其他FP库中有类似Command的接口,我只想知道Guava中是否存在模拟.
使用我的框架的更完整的代码示例可能是这样的:
class Stuff {
private final Stuff CALLS_TO = callsTo(Stuff.class); // a proxy
public static final Command<Stuff> CMD1 = commandFor(CALLS_TO.someMethod1());
public static final Command<Stuff> CMD2 = commandFor(CALLS_TO.someMethod2());
// methods exist for use elsewhere, but …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的.NET MVC 3应用程序上实现此命令模式,专门用于保存对Thing的编辑.我还没有决定如何继续.在我得到实际问题之前,这里是简化的代码:
public class ThingController
{
private readonly ICommandHandler<EditThingCommand> handler;
public ThingController(ICommandHandler<EditThingCommand> handler)
{
this.handler = handler;
}
public ActionMethod EditThing(int id)
{
...build EditThingViewModel and return with View...
}
[HttpPost]
public ActionMethod EditThing(int id, EditThingViewModel vm)
{
var command = new EditThingCommand
{
...not sure yet...
};
this.handler.Handle(command);
...redirect somewhere...
}
}
Run Code Online (Sandbox Code Playgroud)
我的EditThingViewModel完全与我的域断开连接,该域由POCO类组成.看起来我的EditThingCommand应该如下所示:
public class EditThingCommand
{
Thing ModifiedThing;
}
Run Code Online (Sandbox Code Playgroud)
但是,构建ModifiedThing仍然会在我的控制器中发生.这是本案中的大部分工作.在构建ModifiedThing时(以及应用于它的"旧"时间戳进行乐观并发检查),剩下的就是命令在我的数据上下文上调用Update.
显然,能够使用其他命令轻松装饰它是有价值的,但我也希望能够在我的控制器之外移动ModifiedThing的构造.(也许这个问题就是这个问题.)EditThingCommand在我的域中,没有对EditThingViewModel的引用,所以它不能去那里.在我的表示层中有另一个命令将我的viewmodel映射到我的poco实体是否有意义?
single-responsibility-principle command-pattern asp.net-mvc-3
我想在一个小的绘图应用程序中实现undo/redo .似乎命令模式非常适合使用,但我不确定如何最好地实现它.
据我了解的模式,有必要在每个命令中包含:
GeneralPath)我的理解是,每个命令都需要是"原子的"或自包含的,并具有撤消/重做该操作所需的所有信息.
不幸的是,这需要存储比我最初预期更多的信息.对于一条线,我们还必须考虑类似的东西Color,Stroke并且RenderingHints最初用于绘制它.这将我的"简单的小命令"变成了一些东西......在内存中更笨重,并且有更多的样板代码可以生成(每个都是可序列化的bean 1).
出于记忆保护的原因(大多数情况下),我想要"欺骗"命令的规范.也许每100次更新都会备份整个绘图区域,但是不存储已更改图像的任何部分,只需为每次新的绘制操作重建最后(最多)100个命令.但是Graphics在绘制每个零件之前确保对象的状态是正确的似乎是有问题的- 这部分可能需要一条线,但是RenderingHints之前更改了4个命令,之前Color更改了98个命令,而Stroke最后一个保持相同227个命令.
追求更高效的内存命令似乎将模式从"原子"方面抛到了窗外.这反过来导致难以确定可能影响渲染的最早命令.
我是不是该:
Graphics2D(整齐地封装了绘制时使用的许多参数)不可序列化.此外,a BasicStroke 是可序列化的,但不存储笔划的粗细.我可以创建许多属性的可序列化版本,但它似乎会产生更多的代码,所以我将放弃该规范.同样.我只会尝试BufferedImage在运行时存储对引用的引用.我已经编写ASP.NET MVC应用程序一段时间了,我发现它们是使用命令模式的好地方:我们将每个用户请求表示为命令 - 一组输入参数 - 然后处理此命令(处理包括验证和其他域逻辑),结果将发送回用户.
我在我的应用程序中使用的另一件事是视图模型.我发现它们是将数据传递给视图比使用域对象作为模型或填充ViewData/ViewBag更方便的方式.
这两个概念非常适合将显示给用户的数据与用户输入及其处理分开,但它们在ASP.NET MVC中并不完全一致.
假设我想在开发一个简单的网上商店时使用命令和视图模型,用户可以在其中查看产品,并可以通过提供产品名称和电子邮件地址来订购产品:
class ProductViewModel
{
public ProductViewModel(int id) { /* init */ }
public int Id { get; set; }
public string Name { get; set; }
// a LOT of other properties (let's say 50)
}
class OrderProductCommand
{
public int ProductId { get; set; }
[Required(ErrorMessage = "Name not specified")]
public string Name { get; set; }
[Required(ErrorMessage ="E-Mail not specified")]
public string Email { get; set; }
public CommandResult …Run Code Online (Sandbox Code Playgroud) 将HystrixCommand对象实现创建为Singleton 是否正确?如果是这样,它将保留线程直到执行完成并且不再创建了吗?
我正在尝试为命令本身实现具有强类型输入和输出参数的命令模式.
首先,我创建了两个标记命令输入和输出的接口:
interface IRequest { }
interface IResponse { }
Run Code Online (Sandbox Code Playgroud)
然后我创建了基类和接口.这是抽象的接收器
interface IReceiver<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
TResponse Action( TRequest request );
}
Run Code Online (Sandbox Code Playgroud)
这是抽象的命令
abstract class AbstractCommand<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
protected IReceiver<TRequest, TResponse> _receiver;
public AbstractCommand( IReceiver<TRequest, TResponse> receiver ) {
_receiver = receiver;
}
public abstract TResponse Execute( TRequest request );
}
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试使用这些对象,因此我创建了所需的具体类
class TypeARequest : IRequest
{
public TypeARequest() {
}
public int NumericValueA { …Run Code Online (Sandbox Code Playgroud) 关于正确使用流和地图,我有以下问题。
问题如下
我有一种方法可以从输入中读取文件并将记录插入数据库中,简而言之,它会产生一些副作用
此外,同一个函数返回某种状态,让我们说一个布尔值(我对此有一定的自由度)表明函数运行良好。
public static boolean execute(String filename){
// Perform some side effects (e.g. write on DB)
return true; // or false according to some criteria;
}
Run Code Online (Sandbox Code Playgroud)
然后,我必须用两个文件来调用它,我必须检测至少一个文件是否运行良好(即,如果至少一个执行返回 true)
我的简单解决方案是:(一种命令模式的简化版本)
public class Entrypoint {
public static boolean myFunction(String input) {
System.out.println("executed..." + input);
return !input.equals("B");
}
public static void main(String[] args) {
List<String> lst = Arrays.asList("A", "B", "C", "D", "E", "F");
long callsOk = lst.stream().map(Entrypoint::myFunction)
// .filter(x -> x.equals(true)).count();
.filter(x -> x).count(); // Better, as suggested by Donat …Run Code Online (Sandbox Code Playgroud) 以下简单的实体...
public class MyEntity
{
[MaxLength(100)]
[Required]
public string Name { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
...是否可以读取正在装饰"Name"属性的数据注释并验证ChangeName方法中指定的值,以便ValidationResults可以连接到其他验证结果.我假设使用MethodInfo或PropertyInfo对象有些怎么样?
我有这个,但感觉非常笨拙.
public ValidationResult ChangeName(string value)
{
var property = GetType().GetProperty("Name");
var attribute = property.GetCustomAttributes(typeof(MaxLengthAttribute), true)[0] as MaxLengthAttribute;
if (attribute == null) return null; //yield break;
if (value.Length > attribute.Length)
{
return new ValidationResult(NameValidation.NameTooLong);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够从我的验证器中的方法调用ChangeName(value),就像这样.
private IEnumerable<ValidationResult> ValidateMyEntity(MyEntityAddCommand command)
{
MyEntity myEntity = new MyEntity();
yield return myEntity.ChangeName(command.Name);
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我读到的大多数内容都说数据注释是针对CRUD而不是DDD,但为什么不使用它们,因为它们是描述验证行为的好方法,它将与我的MVC视图模型上的数据注释验证一致.有没有更好或更简洁的方法可以做到这一点?所有建议都赞赏.
c# validation domain-driven-design command-pattern data-annotations
这里讨论了Command和Servant模式的相似之处.但另一方面,我看到仆人与访客非常相似,而且非常相似,我不知道有什么区别?两者都通过添加功能为其他类对象服务.但命令模式不会添加功能,而是包装它,对吧?请解释一下我的困惑在哪里.
command-pattern ×10
c# ×3
java ×3
asp.net-mvc ×1
guava ×1
hystrix ×1
java-8 ×1
java-stream ×1
oop ×1
side-effects ×1
single-responsibility-principle ×1
singleton ×1
threadpool ×1
undo ×1
undo-redo ×1
validation ×1
wcf ×1