1)我知道if…else if语句是如何工作的,但在下一个例子中,就结果值而言,两种方法都是相同的.那么我使用的两种方法中的哪一种或者我应该总是选择一种在语义上最接近代码尝试的方法(这里我猜这两种方法在语义上是完全不同的)?那么你会使用哪种方法?为什么?
protected string GetNumberDescription(int value)
{
if (value >= veryBigNumber)
return veryBigNumberDescription;
else if (value >= bigNumber)
return bigNumberDescription;
else if (value >= smallNumber)
return smallNumberDescription;
else
return "";
}
protected string GetNumberDescription(int value)
{
if (value >= veryBigNumber)
return veryBigNumberDescription;
if (value >= bigNumber)
return bigNumberDescription;
if (value >= smallNumber)
return smallNumberDescription;
else
return "";
}
Run Code Online (Sandbox Code Playgroud)
2)我注意到在编写if ... else if语句时丢失的代码使用以下格式:
if ...
else if ...
else ...
Run Code Online (Sandbox Code Playgroud)
但不是(至少在概念上)更正确的方式:
if ...
else
if ...
else …Run Code Online (Sandbox Code Playgroud) 1)我知道以下好处:
它们会增加抽象级别,因为您可以立即看到底层积分值代表什么.
您可以使用它们而不是幻数,并通过这样做使代码更容易理解
它们还限制enum变量可以具有的值,这样做可以使应用程序更安全,因为程序员知道哪些值对变量有效,所以我猜它们提供类型安全性
他们提供的直接使用积分值还有其他好处吗?
2)为什么他们使用积分作为基础类型而不是字符串?
谢谢
通过指定-pe开关(使用Makecert实用程序),我们可以将私钥导出.
a)私钥可以出口是什么意思?我们可以将创建的.pvk文件(包含私钥)复制到另一个系统并在那里使用它?
b)如果是这样,那么我假设.pvk仅在要导出私钥时才创建?!因此,当我们不想导出私钥时如何使用/获取私钥,因此–pe在创建证书时不指定switch?
谢谢
1)当Domain层使用Infrastructure Service IS时,其接口在Domain层中定义,而其实现在Infrastructure层中定义.
我们不应将IS(例如存储库或电子邮件服务)直接注入域实体:
class Foo
{
IRepository repo;
...
public int DoSomething()
{
var info = repo.Get...;
...
}
}
Run Code Online (Sandbox Code Playgroud)
相反,如果域实体的某个方法需要特定的IS,那么Application层可以将该IS作为该方法的参数传递:
class Foo
{
...
public int DoSomething(IRepository repo)
{
var info = repo.Get...;
...
}
}
Run Code Online (Sandbox Code Playgroud)
a)我假设IS也不应该直接注入域服务:
class TransferService
{
IRepository repo;
...
public bool Transfer()
{
var info = repo.Get...;
...
}
} …Run Code Online (Sandbox Code Playgroud) 我为这么多问题道歉,但我觉得他们只有在被视为一个单位时才最有意义
注 - 所有引用均来自DDD:处理软件核心的复杂性(第250和251页)
1)
操作可以大致分为两类,命令和查询.
...
返回结果而不产生副作用的操作称为函数.函数可以多次调用,每次返回相同的值.
...
显然,在大多数软件系统中都无法避免命令,但可以通过两种方式缓解问题.首先,您可以在不同的操作中严格隔离命令和查询.确保导致更改的方法不返回域数据并尽可能简单.在不会导致可观察到的副作用的方法中执行所有查询和计算
a)作者暗示查询是一个函数,因为它不会产生副作用.他还指出函数将始终返回相同的值,我认为他的意思是,对于相同的输入,我们将始终获得相同的输出?
b)假设我们有一个QandC(int entityId)查询特定域实体的方法,从中提取某些值,这些值又用于初始化一个新的值对象,然后将该VO返回给调用者.是不是根据上面的引用QandC功能,因为它不会改变任何状态?
c)但是作者还争辩说,对于相同的输入,函数总是会产生相同的输出,但事实并非如此QandC,因为如果我们进行多次调用QandC,它将产生不同的结果,假设在两次调用之间的时间内实体已被修改甚至删除.因此,我们如何宣称QandC是一种功能?
d)
确保导致更改的方法不返回域数据...
原因是在未来的某些操作中可能会改变返回的非VO的状态,因此这些方法的副作用是不可预测的?
E)
确保导致更改的方法不返回域数据...
是一个返回仍被视为函数的实体的查询方法,即使它没有更改任何状态?
2)
VALUE OBJECTS是不可变的,这意味着除了仅在创建期间调用的初始化器之外,它们的所有操作都是函数.
...
将逻辑或计算与状态更改混合的操作应重构为两个单独的操作.但根据定义,这种将副作用分离为简单命令方法仅适用于ENTITIES.完成重构以将修改与查询分开后,考虑进行第二次重构以将复杂计算的责任转移到VALUE OBJECT中.通过导出VALUE OBJECT而不是更改现有状态,或将整个职责移动到VALUE OBJECT,可以完全消除副作用.
一个)
VALUE OBJECTS是不可变的,这意味着除了在创建期间调用的初始化器之外,它们的所有操作都是函数......但是根据定义,这种将副作用分离为简单命令方法仅适用于ENTITIES.
我认为作者说VO上定义的所有方法都是函数,这没有意义,因为即使在VO上定义的方法不能改变它自己的状态,它仍然可以改变其他非VO对象的状态. ?!
b)假设在实体上定义的方法不会改变任何状态,我们是否认为这样的方法是一个函数,即使它是在一个实体上定义的?
C)
...考虑进行第二次重构,将复杂计算的责任转移到VALUE OBJECT.
为什么作者建议我们只应该从那些执行复杂计算的函数中重构?为什么我们不应该重构更简单的函数?
d)
...考虑进行第二次重构,将复杂计算的责任转移到VALUE OBJECT.
无论如何,为什么作者建议我们应该从实体中重构函数并将它们放在VO中?只是因为它使客户端更明显地认为这个操作可能是一个函数?
E)
通过导出VALUE OBJECT而不是更改现有状态,或将整个职责移动到VALUE OBJECT,可以完全消除副作用.
这没有意义,因为如果我们将一个命令(即改变状态的操作)移动到一个VO中,那么作者就是在争论,那么即使命令正在改变状态,我们实质上也会消除任何副作用.所以任何想法,作者究竟试图说什么?
更新:
图1b)
这取决于观点.数据库查询不会改变状态,因此没有副作用,但它本质上不是确定性的,因为当您指出数据可以改变时.在本书中,作者指的是与价值对象和实体相关联的函数,这些函数本身不会进行外部调用.因此,规则不适用于QandC.
所以作者只描述了不进行外部调用的函数,因此不是作者描述的函数QandC类型?
1C)
QandC本身不会改变状态 - 没有副作用.然而,基础状态可以在带外改变.因此,它不是一个纯粹的功能.
但它也不是意义作者定义的Side-Effect-Free功能吗?
1D)
同样,这是基于CQS. …
1)
1 - 只处理您实际可以做的事情,
2 - 您无法对绝大多数例外做任何事情
a)我假设“By not handling an exception”文本建议我们应该让异常冒泡到堆栈中,运行时将中止我们的应用程序?!
b)但是为什么让运行时中止异常优先于捕获异常,记录它然后通知用户失败?只有两者之间的区别在于,在后一种情况下,应用程序不会中止
例如,如果数据库出现故障,为什么整个程序崩溃(由于没有处理异常),如果我们可以捕获异常,记录它并通知用户失败,那样我们就可以保持程序正常运行
2)如果您知道某些代码块可能引发的异常无法处理,您是否应该在try-finally块中包含此代码,或者最好将其保留在任何try-finally块之外?
谢谢
根实体可以将对内部实体的瞬态引用传递给外部对象,但是在操作完成后外部对象不能保留该引用的条件下
1)
a)为什么外部对象在单个操作的持续时间内具有引用(对于内部实体)是可接受的,但在两个操作的持续时间内保持该引用是不可接受的?我的观点是,如果在两次操作的持续时间内保持参考是不好的,那么在一次操作的持续时间内坚持它可能同样糟糕吗?!
b)假设SomeRootEnt 聚合根将内部实体的瞬时引用 传递SomeIntEnt给外部对象,外部对象应该如何请求SomeIntEnt?通过在根上调用特定方法- 例如SomeRootEnt.BorrowMeIntEnt(...)- 或者root应该直接暴露内部实体作为其属性(例如SomeRootEnt.SomeIntEnt)?
2)
a)假设SomeRootEnt root将对内部实体 的引用传递SomeIntEnt 给外部对象,而外部对象又对其进行了一些修改SomeIntEnt,那么这并不意味着root无法对这些修改应用适当的不变逻辑(即root无法检查修改后的完整性SomeIntEnt?
b)同样,根据我的理解,至少在完成单个操作后,root也无法强制外部对象删除对内部实体的引用?
谢谢
更新:
图2a)
这是正确的,这就是为什么最好确保传递的对象不被修改,而是以不可变的方式使用.而且,被传递的实体本身仍然可以保持一定程度的完整性.
它主要是Aggregate …
1)据我所知,无法建立只连接客户端以提供证书的SSL连接.知道为什么SSL不允许这样做吗?
2)我假设SSL连接可以配置为:
3)可能是一个愚蠢的问题,但SSL如何"知道"哪一方是客户端,哪一方是服务器?
4)是否可以在没有SSL请求任何证书的情况下建立SSL连接?
谢谢
假设Net进程P在Windows帐户下运行A1.我假设如果线程(P在其中运行)在某个其他身份(通过获取Thread.CurrentPrincipal.Identity)下运行A1,它仍然具有与A1访问系统资源(例如文件等)时相同的权限?
谢谢
当操作在概念上不属于任何实体或值对象时,我们应该创建域服务,而不是将行为强制转换为对象.
应根据域模型的其他元素定义服务的接口.换句话说,Service shold的参数和返回值是域对象
a)为什么/必须域服务使用域对象作为参数并返回值?
b)为什么DDD也不要求实体和值对象的方法将域对象用作参数并返回值?为什么这个约束只放在服务上呢?
谢谢
EULERFX:
1)
这两种约束都促进了不变性和功能性风格
a)这两个约束如何促进不变性?
b)什么是功能风格?
c)因此我们应该尝试(因为它可能并不总是可能使用强制)来强制服务使用域对象作为参数并返回值,即使该服务(即行为)接受/返回可能更自然非域对象?
2)
实体和值对象组成更原始的类型以形成复杂类型,并且一些行为可能依赖于原始参数.
那么,由于域实体/值对象的某种内在特征,在大多数情况下,它们的行为(即它们的操作)对基本类型进行操作(即使用基元类型作为参数)?如果是,那么在大多数情况下,这是在域对象中发现的内在特征,但在域服务中很少?
第二次更新:
这两个约束如何促进不变性?
这个想法是域服务不会改变状态,所有状态更改都通过参数显式化.
a)不改变自己的状态或某个域对象的状态?由于域名服务应该是无状态的,我认为你的意思是它不应该改变DO的状态?换句话说,服务通过确保将其修改的任何DO作为参数传递给它(即传递给它的操作)来提升不变性?
b)但是如果相反DO被服务修改不作为参数传递,那么我们说域服务突变了这个DO的状态?
c)改变DO的状态被认为是坏事的原因是因为它不能提高清晰度(即,当查看服务操作的签名时,它不会立即明显,哪些DO将通过操作)?
d)如果域服务将修改作为参数传递给它的DO的状态,那么它是理想的,如果它将用于改变该DO状态的值也将作为参数传递给服务.如果是的话,是因为它促进了清晰度还是......?
2)我仍然不明白返回值与参数类型相同如何促进不变性?
EULERFX 3
一个)
域服务可以通过返回对象的新实例而不是修改传入的对象来避免状态突变.
这不是一个问题,更多的是一个观察,但有些困难理解为什么这种服务行为在大多数领域模型中是常见的,甚至在建模领域时这种行为是否自然而然或者我们必须强迫它进入概念?
b)
是的,虽然在这种情况下,域对象改变自身会更好.
DO应该变异的主要原因是因为在特定DO上执行变异的代码集中在一个地方,所以如果我们需要检查这个代码,我们知道在哪里寻找它?