根据任意逻辑将对象简化为类别

本文关键字:对象 任意逻 | 更新日期: 2023-09-27 18:16:54

这个问题可能比较主观。我不确定它是属于这里还是属于Programmers

假设我有一个数据类型X(考虑从关系数据库构造的业务对象)。我的最终目标是在一个报表的表格中表示这种类型的许多实例,每个实例在几个不同的标题下。

显示对象的标题是根据管理层传递的任意逻辑选择的,任何做过企业软件开发的人都应该熟悉:

例子:

If the instance has a FooID of 6 and a BarFactor of < 0.5, place it under the "Borked" heading.

If the Weight is > 0, and the CreatedDate is before Midnight but after 3PM, and today is not the 3rd Wednesday of the month, the object should be categorised as "Fluffy".

我的问题:是否有一种常见的习惯用法,用于获取X的实例,将可能引起头痛的逻辑量应用于实例的状态,并从该逻辑的结果中获得类别/字符串/任意值?


目前为止我的想法是:

  1. 一个接受X并返回String的函数。我可以很容易地看到它变成了一个巨象,并且需要一个b*****来维护,因为需求是不断修改的。

  2. 定义一个Heading抽象类型和一个工厂函数,它给我一个Heading的实例,ToString方法正确重载。我认为这一技术将会受到与第一个想法相同的问题的困扰。1 .

  3. 函数的层次结构,每个函数都将问题进一步分解,直到我们到达正确的标题。

例如:

public String GetHeading(X x) 
{
    if (x.Weight > 0)
        return WeightGreaterThanZero(x);
    else if (x.Weight < 0)
        return WeightLessThanZero(x);
    else
        return WeightIsZero(x);
}

三个"Weight"函数将测试进一步的条件,直到我们得到一个值。我在这里看到的问题是,我们需要跟踪哪个函数调用了哪个函数。FooIDIs6函数需要知道它是由WeightIsZero还是其他函数调用的,否则前面的任何决定都可能毫无意义。最后是WeightIsGreaterThanZero_FooIDIs6_GrandmotherIsOlderThan100等等等等

根据任意逻辑将对象简化为类别

我不确定这是否完全适用于您想要完成的任务,但每当我们遇到这种"乐趣"时,我们最终都会为业务用户提供一个用户界面来定义他们的规则,然后编写足够的代码将规则应用于特定对象。

例如,在我们的一个应用程序中,我们允许用户指定一组条件,当求值为true时,将产生用户定义的输出。

为此,我们在数据库中为IF语句的每个部分存储一条记录。每条记录指定类中的属性名称、比较操作(<、=、<>等)、比较值、语句是开始还是结束一个组(即父语句),以及当前语句如何与下一个语句连接(and或or)。

也就是

Heading Record (Parent record, which defines the heading to be used)
  Heading Selector (Child records which define the if statement)

我们还可以在父记录中支持用户自定义的优先级,这样如果给定的记录有多个匹配,则用户有责任通过适当的应用优先级来确定最佳匹配。

在运行时,您只需构建一条语句来计算用户输入的条件。我们使用反射,这样我们就不必硬编码属性名。

此外,在更适合在SQL中执行选择逻辑的情况下,可以使用相同的配置代码来生成SQL语句。

我们已经广泛地使用了这种机制,并发现它是满足客户频繁和不同需求的一种非常强大的方法。

如果一组类别类接受一个X并指出它是否是该X的正确类别呢?比如:

var categories = new Category[] { new FooCategory(), new BarCategory(), new FluffyCategory() };
foreach( var x in myListOfXs ) {
  var cat = categories.FirstOrDefault(c => c.Matches(x));
  if( cat != null ) {
    x.Category = cat.Name;
  }
}