首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >表示域对象

表示域对象
EN

Software Engineering用户
提问于 2012-12-21 19:21:56
回答 1查看 292关注 0票数 3

这与我的最近的问题有关命名尴尬的域对象有关。许多答案表明我对域对象使用了错误的表示形式。总之,我选择使用枚举来表示某些域对象,这些对象用作查找中的键。

对于这个问题,我想回顾一下我使用枚举的决定,并找出替代方案。跳到我的问题的底部为TL;

域描述

我的应用程序负责执行一些涉及化学化合物的计算。

一些基本方程是:

  • 计算化合物的摩尔数
  • 计算不同浓度下化合物的比重或密度

这些方程可以作为Chemical类中的方法处理,如下所示:

Chemical.GetMolesFromMass(double mass_grams)

Chemical.GetDensity(double concentration)

也可以将它们实现为泛型化学属性类之外的方法,如:

Chemical.GetMolesFromMass(Compound cmpd, double mass_grams)

Chemical.GetDensity(Compound cmpd, double concentration)

我认为,从对象责任的角度来看,Chemical类之外的方法的第一个选项是更好的表示。

一些高级方程式包括:

  • 计算业务流程消耗的化合物的数量
  • 计算化合物的储存要求
  • 基于标准集装箱尺寸的配送优化

在这些方程中,化合物是该方法的输入。

StorageTankCluster.Generate(Compound cmpd, double requiredVolume)

StorageTankCluster需要了解化学物质,因为星团内储罐的尺寸和间距将根据化学物质和所需体积而变化。储存的化学物质会影响储罐材料的选择,也会影响储罐之间的安全间隙。

目前,我正在考虑这些参数(间距,材料,.)作为查找项,而不是化合物负责了解的元素。

同样,配送优化受化学化合物的影响,但这些方面是否是化合物的责任是有争议的。

StorageTankCluster和交付优化组件都打算被应用程序的其他非化学方面重用。由于这个问题已经变得越来越复杂,我们只需将这些其他元素称为FooBarFooBar都可以利用传递优化,但只有Foo可以与StorageTankCluster一起使用。

它现在不在应用程序中,但是到目前为止讨论的所有各种属性都需要存储在数据库/持久层中。我意识到这不应该影响一个好的设计,但我认为这是值得一提的。

我承认,我的一些决定是有偏见的,因为我正在从另一个来源移植这个应用程序,它强制以结构化的方式完成所有工作。写出这个问题突出了几个领域,我应该更好地检查哪些对象对该功能负有责任。

到目前为止,我的设计都是围绕查找表进行的,我使用枚举值作为这些表的键。正是它们作为密钥的使用,使我将它们作为程序中的命名对象来处理,而不是将它们作为系统将操作的对象。这几乎把化学化合物降到了二级等级,我想知道这是否是正确的决定。另一方面,我担心化学化合物类会变得过于臃肿。

TL;DR

我的实现是/必须在C#中。所以使用枚举是正确的选择,或者我应该做什么,为什么?

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2012-12-22 00:28:20

我们希望代码尽可能简单。我们不希望它被程序员不需要知道的领域知识弄得乱七八糟。因此,只要有可能,我们都希望避免将某些特定于化学产品的领域放入代码中。这就是为什么我们认为将化学产品作为enum放入您的代码中可能是个坏主意,除非事实证明并非如此。

作为一个类似的案例,考虑一个课程注册制度。您不希望代码包含对人们应该参加的各种课程的任何引用。CSI101可能是“计算机图形学入门”,但在代码中根本不应该出现这种情况。该信息只应位于课程的数据库行中。课程注册系统代码对待所有类都是一样的,可能只考虑课程的名称、先决条件、学分等属性。

第一个问题是,你是否真的需要在你的代码中引用各种化合物。这与您是否使用查找表无关。无论Chemical.GetDensity(Compound cmpd, double concentration)是枚举、对象、字符串还是int,Compound都可以同样工作。StorageTankCluster.Generate(Compound cmpd, double requiredVolume),是相同的,函数的工作原理是相同的,不管这些化合物是否在代码中被命名为实体。这些事情都不需要你在代码中引用化合物。

当然,在某个地方你必须指定考虑哪种化合物。它不可能总是函数的参数。正是该规范的性质决定了您是否需要在代码中引用化学品。您的声明似乎表明业务流程决定了需要考虑哪些化合物。我认为业务流程是编写成代码的,这就是为什么您需要在代码中引用化学化合物。但问题是,业务流程是否真的需要在代码中实现。

为了明白我的意思,让我们回顾一下课程注册情况。假设您有一个类,对于是否允许您接受它,有一个复杂的规则。

代码语言:javascript
复制
boolean CSI250::MayTake(Student student)
{
    // if the student has special permission, he can always take the course
    if( student.HasOverrideForCourse("CSI250") ) return true;

    // Student must have taken 101 first
    if( !student.HasTaken("CSI101") ) return false;

    // Student must have at least a B in CSI 101
    if( student.GetGrade("CSI101") < Grades.B) return false

    // Student must have taken either CSI150 or CSI201
    if( !student.HasTaken("CSI150") || !student.HasTaken("CSI201") ) return false;

    return true;
}

如果我的理解是正确的,你需要一个枚举,因为你指的是你的过程中的各种化学产品,就像我在上面的课程中所做的那样。(我使用过字符串,但我也可以使用枚举。)但是,上面的代码不是一个好主意,因为它将太多的域信息投入到这个过程中。这将是一个痛苦的维持作为权力,是调整和调整的事情。所以我们想要做的是将前提信息存储在数据库中,如下所示:

代码语言:javascript
复制
Course   Prereq    Grade Required   Alternate    Grade Required
CSI250   CSI101    B
CSI250   CSI150    D                CSI200       B

现在,先决条件信息从代码移到数据库中。它可以由管理部门操作,代码更简单,等等。问题是您是否可以对您的业务流程做同样的操作。将代码中的类似内容移到数据中有很多好处。也许你做不到,但这是我想要做的。

即使您必须将这些实体放入代码中,我也可能避免使用enumenums很蠢。我认为能说:Chemicals.SodiumPhosphate.GetMolesFromMass(1000)比说GetMolesFromMass(Chemicals.SodiumPhosphate, 1000)更好。它还为您提供了未来的灵活性,因为该方法可以做它想做的任何事情。它可以使用查找表,也可以将数据存储在其中,或者其他什么。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/180335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档