关于为大域对象创建工厂的建议
我们有一个大对象图,其中有很多属性和行为。我们目前正在重新审视我们的领域,我们将采用 DDD 方法。但我们需要各位专家就如何为我们的大域模型创建工厂提供建议。
问题
我们服务于多个地区,如美国、加拿大、西班牙、智利、巴西、英国等。很明显,每个地区的地址、姓名((姓氏、姓氏 1、姓氏 2 等))、电话号码都存在差异、国家身份证等。在高层次上,域模型看起来像这样
- 一个交易可以有多个 主题的
- 主题有名字, 地址、电话号码、国民 ID
- 主题可以是 ConsumerSubject 或 BusinessSubject
- 或 ConsumerSubject 有 PersonName 而 BusinessSubject 有一个 BusinessName
- 地址可以是 美国地址、英国地址、 加拿大地址、智利地址等 同样的方式也可以有 地理特定子类 大多数域对象(其中 适用)
对于每个新请求,我们需要创建以有效状态正确填充的整套对象。我们可以使用抽象工厂模式来拥有特定于地理的工厂,如 USTransactionFactory、CanadianTransactionFactory 等。
这里需要建议
如何传入参数来创建这些对象。以Address为例
- 我们是否应该有一个createXXXAddress(...)方法 每个包含城市的地理区域, 状态等作为输入参数? 这 意味着我们需要有 创建美国地址(...), 创建加拿大地址(...), createChileanAddress(...) 等
或者我们应该只有一个 createAddress(Address addr) 方法 只需要 Address 对象和 让客户创建 适当的地理特定 地址对象?例如
西班牙地址西班牙=新西班牙地址(); spain.setMuniciplaityName(...);或者我们应该为每个重要的域对象拥有一个单独的 AbstractFactory? 例如 USAddressFactory、UKAddressFactory 等
这里需要建议
是否有必要为此创建 DTO? 我想只是将域传递到表示层,但通过强制读取来保持不变性仅域视图。例如,每个域对象将实现两个接口:ReadOnlyAddress、MutableAddress。这是受到 joda-time 的启发。
欢迎任何其他建议和批评。
We have a big object graph with lot of properties and behavior in it. We are currently revisiting our domain and we are going to go the DDD approach. But we are in need of a suggestion from you experts on how to go about creating Factories for our big domain model.
Problem
We cater to multiple geographies like US, Canada, Spain, Chile, Brazil, UK etc. As it is evident each one of then have differences in addresses, names ((last name, surname 1, surname 2 etc)), phone numbers, national IDs etc. At a high level the domain model looks like this
- a Transaction can have multiple
Subject's - a Subject has Name,
Address, TelephoneNumber, NationalID - a Subject can be a ConsumerSubject
or a BusinessSubject - a ConsumerSubject has a PersonName
while a BusinessSubject has a
BusinessName - a Address can be a
USAddress, UKAddress,
CanadianAddress, ChileAddress etc
and the same way there can be
geography specific subclasses for
most of the domain objects (where
applicable)
For every new request we need to create this entire set of objects properly populated in a valid state. We can use the Abstract Factory pattern to have Geography specific factories like USTransactionFactory, CanadianTransactionFactory etc.
Required Suggestion here
How to pass-in the parameters to create these objects. Taking Address as an example
- Should we have a createXXXAddress(...) method for
each geography that takes in city,
state etc as input arguments? This
means that we need to have
createUSAddress(...),
createCanadianAddress(...),
createChileanAddress(...) etc OR should we just have one createAddress(Address addr) method
that just takes Address object and
let the client create the
appropriate geography specific
Address object? E.g
SpainAddress spain=new SpainAddress();
spain.setMuniciplaityName(...);OR should we have a separate AbstractFactory for each of the significant domain objects? For e.g USAddressFactory, UKAddressFactory etc
Required Suggestion here
Is there a necessity to create DTO's for this? I am thinking just pass the domain to presentation layer but maintain immutability by enforcing read-only view of the domain. For e.g each domain object will implement two interfaces: ReadOnlyAddress, MutableAddress. This was inspired by how joda-time.
Any other suggestions and criticisms are welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我绝对不推荐选项 1:它会导致将客户端代码绑定到特定地理位置,可能需要大量
switch
/if- else
语句分散在各处,并且每当添加/删除地理位置时,每个语句中的代码都会发生变化 - 多态性要解决的确切问题。我不太清楚选项 2 和 3 之间的确切区别,但我的第一个方法是使用某种 GeographyFactory 来生成部分或整个对象图在此描述。因此,客户端将调用单个 createAddress 方法,但该方法本身是多态的。
工厂是直接依赖注入到客户端还是在后台(部分)透明地使用(类似于 C++ 中的语言环境)取决于具体情况 - 两种方法都可以。
关于地址,我会尝试仅通过不可变对象来摆脱 - 如果地址发生变化,您只需创建一个新对象并丢弃旧对象即可。请注意,地址很少是第一类实体,而是代理值对象(即没有自己的标识)。但当然,很大程度上取决于对象关系映射解决方案和数据库模式的细节。
I would definitely not recommend option 1: it would result in binding client code to specific geographies, probably requiring lots of
switch
/if-else
statements scattered all over the place, and code changes in each of those whenever geographies are added/removed - the exact problem polymorphism was meant to resolve.I am not quite clear about the exact difference between your options 2 and 3, but my first approach would be to use some sort of a GeographyFactory to produce part(s) or the whole of the object graph you describe here. Thus clients would call a single
createAddress
method but the methodf itself would be polymorphic.Whether the factory would be dependency injected directly to the client or used (partly) transparently in the background similar to a locale in C++ depends on the circumstances - both approach may be fine.
With regards to addresses, I would try to get away by immutable objects only - if an address changes, you can just create a new object and throw away the old one. Note that addresses are rarely first-class entities, but rather surrogate value objects (i.e. have no identity of their own). But of course, a lot depends on the details of your object-relational mapping solution and the DB schema.