我刚刚开始学习Swift(v.2.x),因为我很好奇新功能是如何发挥作用的,尤其是具有Self-requirements的协议.
以下示例将编译得很好,但会导致任意运行时效果发生:
// The protocol with Self requirement
protocol Narcissistic {
func getFriend() -> Self
}
// Base class that adopts the protocol
class Mario : Narcissistic {
func getFriend() -> Self {
print("Mario.getFriend()")
return self;
}
}
// Intermediate class that eliminates the
// Self requirement by specifying an explicit type
// (Why does the compiler allow this?)
class SuperMario : Mario {
override func getFriend() -> SuperMario {
print("SuperMario.getFriend()")
return SuperMario();
}
}
// …Run Code Online (Sandbox Code Playgroud) 我不知道细节,但据我了解合并和冲突解决的过程,它如下(假设存储库中只有一个文件,在两个分支中修改):
git merge命令.<<<<<<<,|||||||,=======,>>>>>>>标记).然后它将其状态设置为"合并"或类似.git mergetool ...配置的外部合并工具打开,参数指向BASE,LOCAL,OTHER,当然还有MERGED.有几点我很困惑:
diff3选项怎么样?它是否也被外部工具普遍理解?我找不到真正讲述整个故事的任何解释.
一些消息来源声称流程管理器不包含任何业务逻辑。例如,微软的一篇文章是这样说的:
\n\n\n您不应使用流程管理器在您的域中实现任何业务逻辑。业务逻辑属于聚合类型。
\n
再往上他们还这么说(强调我的):
\n\n\n需要注意的是,流程管理器不执行任何业务逻辑。它仅路由消息,并且在某些情况下在消息类型之间进行转换。
\n
但是,我不明白为什么消息之间的转换(例如从域事件到命令)不是业务逻辑的一部分。您需要领域专家才能知道正确的步骤顺序以及步骤之间的转换。在某些情况下,您还需要在步骤之间保留状态,甚至可能根据某些(业务)条件选择后续步骤。因此,并非所有内容都是给定步骤的静态列表(尽管我\xe2\x80\x99d 也调用业务逻辑)。
\n在我看来,在很多方面,流程管理器(或就此而言的传奇)只是另一种持久状态的聚合类型,并且可能具有一些业务不变量。
\n假设我们用六边形架构实现 DDD,I\xe2\x80\x98d 将进程管理器放置在应用程序层(不是适配器!!),以便它可以对消息做出反应或由计时器触发。它将通过存储库加载相应的流程管理器聚合,并调用其上的方法来设置其(业务)状态或要求其发送下一个命令(当然,实际发送是由应用程序层完成的)。该聚合位于领域层,因为它负责业务逻辑。
\n我真的不明白为什么人们要区分业务规则和工作流规则。如果删除除领域层之外的所有内容,您应该能够重建工作应用程序,而无需再次咨询领域专家。
\n我\xe2\x80\x98d 很高兴从你们那里得到一些我可能缺少的进一步见解。
\nworkflow domain-driven-design business-process-management hexagonal-architecture
所以我现在研究这个主题很长一段时间了,我想我理解最重要的概念,如发布和获取内存栅栏.
但是,我还没有找到令人满意的解释,volatile主存储器的缓存和缓存之间的关系.
因此,我理解对volatile字段的每次读写操作都会对读取以及之前和之后的写入操作执行严格的排序(读取 - 获取和写入 - 释放).但这只能保证操作的顺序.它没有说明这些更改对其他线程/处理器可见的时间.特别是,这取决于刷新缓存的时间(如果有的话).我记得曾读过Eric Lippert的评论,他说" volatile字段的存在会自动禁用缓存优化".但我不确定这究竟是什么意思.这是否意味着整个程序的缓存完全被禁用,因为我们在volatile某处有一个字段?如果不是,禁用缓存的粒度是多少?
此外,我读到了一些关于强和弱的易失性语义的东西,并且C#遵循强大的语义,即每次写入都将直接进入主存储器,无论它是否是一个volatile字段.我对这一切感到非常困惑.
我对在基于六边形架构的应用程序中处理域事件的位置感到困惑。我说的是有界上下文内部域事件,而不是上下文间集成/应用程序/公共事件。
背景
据我了解,应用程序逻辑(即用例逻辑、工作流逻辑、与基础设施的交互等)是命令处理程序所属的地方,因为它们特定于特定的应用程序设计和/或 UI 设计。然后命令处理程序调用域层,所有域逻辑都驻留在其中(域服务、聚合、域事件)。领域层应该独立于特定的应用程序工作流程和/或 UI 设计。
在许多资源(博客、书籍)中,我发现人们在应用程序层中实现域事件处理程序,类似于命令处理程序。这是因为域事件的处理应该在其自己的事务中完成。由于它可能会影响其他聚合,因此必须首先通过基础设施加载这些聚合。然而,关键点是:领域事件被分解并变成对聚合的一系列方法调用。这个重要的转换仅存在于应用层。
问题
我认为关于哪些领域事件会对其他聚合产生什么影响的知识是领域知识本身的一个组成部分。如果我要删除除域层之外的所有内容,那么这些知识不应该保留在某个地方吗?在我看来,我们应该将域事件处理程序直接放置在域层本身中:
它们可以是域服务,接收域事件和可能受其影响的聚合,并将域事件转换为一个或多个方法调用。
它们可以是聚合本身的方法,直接消耗整个域事件(即签名包含域事件类型)并对其执行任何操作。
当然,为了加载受影响的聚合,我们仍然需要在应用层有一个相应的处理程序。该处理程序仅启动一个新事务,加载感兴趣的聚合并调用域层。
由于我从未在任何地方看到过这一点,我想知道我是否对 DDD、领域事件或应用程序层和领域层之间的差异有什么误解。
编辑:示例
让我们从这种常用的方法开始:
// in application layer service (called by adapter)
public void HandleDomainEvent(OrderCreatedDomainEvent event) {
var restaurant = this.restaurantRepository.getByOrderKind(event.kind);
restaurant.prepareMeal(); // Translate the event into a (very different) command - I consider this important business knowledge that now is only in the application layer.
this.mailService.notifyStakeholders();
}
Run Code Online (Sandbox Code Playgroud)
换成这个怎么样?
// in application layer service (called by adapter)
public void HandleDomainEvent(OrderCreatedDomainEvent event) {
var …Run Code Online (Sandbox Code Playgroud) domain-driven-design business-logic hexagonal-architecture domain-events
尝试使用编程语言Rust,我发现编译器能够非常准确地跟踪堆栈中某些结构的字段的移动(它确切地知道哪个字段已移动).但是,当我将结构的一部分放入a Box(即将其放入堆中)时,编译器不再能够确定在取消引用该框之后发生的所有事件的字段级移动.它将假设"盒子内部"的整个结构已经移动.让我们首先看一下一切都在堆栈上的例子:
struct OuterContainer {
inner: InnerContainer
}
struct InnerContainer {
val_a: ValContainer,
val_b: ValContainer
}
struct ValContainer {
i: i32
}
fn main() {
// Note that the whole structure lives on the stack.
let structure = OuterContainer {
inner: InnerContainer {
val_a: ValContainer { i: 42 },
val_b: ValContainer { i: 100 }
}
};
// Move just one field (val_a) of the inner container.
let move_me …Run Code Online (Sandbox Code Playgroud) 如果我的取消引用链中有任何不可变的引用,我似乎无法改变任何东西。一个样品:
fn main() {
let mut x = 42;
let y: &mut i32 = &mut x; // first layer
let z: &&mut i32 = &y; // second layer
**z = 100; // Attempt to change `x`, gives compiler error.
println!("Value is: {}", z);
}
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误:
fn main() {
let mut x = 42;
let y: &mut i32 = &mut x; // first layer
let z: &&mut i32 = &y; // second layer
**z = 100; // Attempt to …Run Code Online (Sandbox Code Playgroud) 我们的项目使用Entity Framework 6.0和.NET 4.5,FAT-Client和Code-First方法.
我们有大约20个迁移文件(C#部分类)通过Add-MigrationVisual Studio包管理器控制台中的cmdlet自动生成,并通过成功应用Update-Database.
现在,我们的客户端有一个集成数据库,已经应用了大约10个迁移,我们现在需要应用剩余的10个迁移.我们使用Update-Database -Script -SourceMigration:<migration10>它来为剩余的迁移生成SQL脚本.在这种情况下 - 以及使用时SourceMigration:$InitialDatabase- 会显示以下错误:
[...]
Applying explicit migration: 201609141617112_HostAufbauIdentifier.
Applying explicit migration: 201609141622583_RemPerStaWe.
System.Xml.XmlException: 'SoftwareAuftrag_Auftrag' is an unexpected token. Expecting white space. Line 1943, position 92.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ThrowExpectingWhitespace(Int32 pos)
at System.Xml.XmlTextReaderImpl.ParseAttributes()
at System.Xml.XmlTextReaderImpl.ParseElement()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options)
at …Run Code Online (Sandbox Code Playgroud) 下面的代码编译(并运行)就好了,即使我希望它产生编译时错误:
#include <iostream>
using namespace std;
template <typename T>
struct is_int {
static const bool value = false;
};
template<>
struct is_int<int> {
static const bool value = true;
};
// General template definition with default second type parameter (void)
template <typename A, typename B = void>
struct Foo {
static const int i = 42;
};
// Partially specialized template definition with possibly
// undefined second parameter
template<typename A>
struct Foo<A, typename enable_if<is_int<A>::value>::type > {
static const int i …Run Code Online (Sandbox Code Playgroud) 我刚刚学会了更高级的kinded类型,但我提供的每个例子都只使用了2级(* -> *) -> *,就像Functor.
在Scala中,使用了奇怪的特征定义,在Haskell中,使用了类型类.并且这两种方法似乎都不能更多地使用一种抽象(即((* -> *) -> *) -> *).
我既不是Scala也不是Haskell的专家,所以如果你能提供这种更高等级类型的简单例子,如果它们可以表达的话,那将会很有帮助.
阅读COM以获取一些遗留项目.到目前为止,我的理解是COM只是一个二进制规范,并且所有实现组件(客户端和服务器)必须遵守此规范.只要我们使用接收和返回简单值类型的方法处理COM接口,一切对我来说都是完美的.
但是,也有可能从COM对象发送指向整个对象/变体(包含例如a SAFEARRAY)的指针,我想知道这些param对象的内存在哪里被分配.我读到它是由windows拥有的内存,我们不应该通过COM方法篡改它.然后我偶然发现了IMallocCOM接口及其Alloc方法,它似乎以COM感知的方式分配了一大堆内存,完美地完成了混乱.
为了不干扰由C++维护的堆结构(假设我们用C++编写COM服务器),究竟在哪里IMalloc分配内存?
假设我有一个实现以下业务规则/策略的域服务:
\n\n\n如果“家庭”类目中所有产品的总价超过100万,则对超过一年的家庭产品降价50%。
\n
使用基于集合的存储库
\n我可以简单地创建一个域服务,使用规范模式加载“系列”类别中的所有产品,然后检查条件,如果为真,则降低价格。由于产品是由基于集合的存储库自动跟踪的,因此域服务不需要像应该那样发出任何显式的基础结构调用 \xe2\x80\x93 。
\n使用基于持久性的存储库
\n我运气不好。我可能会摆脱使用存储库和规范在我的域服务中加载产品的情况(像以前一样),但最终,我需要发出Save不属于域层的调用。
我可以在应用程序层加载产品,然后将它们传递给域服务,最后再次将它们保存在应用程序层,如下所示:
\n// Somewhere in the application layer:\npublic void ApplyProductPriceReductionPolicy()\n{\n // make sure everything is in one transaction\n using (var uow = this.unitOfWorkProvider.Provide())\n {\n // fetching\n var spec = new FamilyProductsSpecification();\n var familyProducts = this.productRepository.findBySpecification(spec);\n\n // business logic (domain service call)\n this.familyPriceReductionPolicy.Apply(familyProducts);\n\n // persisting\n foreach (var familyProduct in familyProducts)\n {\n this.productRepository.Save(familyProduct);\n }\n\n uow.Complete();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但是,我发现这段代码存在以下问题:
\nc# ×2
c++ ×2
rust ×2
algorithm ×1
business-process-management ×1
caching ×1
com ×1
compile-time ×1
dynamic ×1
file-format ×1
git ×1
haskell ×1
heap ×1
immutability ×1
mergetool ×1
mutability ×1
scala ×1
stack ×1
swift ×1
templates ×1
traits ×1
type-safety ×1
typeclass ×1
typesafe ×1
volatile ×1
winapi ×1
workflow ×1