Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 当域是动态的/变化的时,如何处理域驱动的设计_Oop_Domain Driven Design - Fatal编程技术网

Oop 当域是动态的/变化的时,如何处理域驱动的设计

Oop 当域是动态的/变化的时,如何处理域驱动的设计,oop,domain-driven-design,Oop,Domain Driven Design,为了明确我的意思,让我们构建一个可能需要的假设场景 假设我正在为一家管理苏格兰威士忌酿酒厂的公司开发一些软件。每个啤酒厂公司都可以拥有该软件的副本,以管理所有的商业物流 假设我有一个水壶对象,它上面有一些属性,例如.color和.Material 但如果格兰菲迪啤酒厂想在这块土地上拥有另一处地产,该怎么办?e、 g..Size和其他一些啤酒厂并不关心上述所有内容,只对.Content和感兴趣 在OOP中,是否有一种方法可以根据名为Customer的某些参数使我的Kettle对象动态(具有不同的属

为了明确我的意思,让我们构建一个可能需要的假设场景

假设我正在为一家管理苏格兰威士忌酿酒厂的公司开发一些软件。每个啤酒厂公司都可以拥有该软件的副本,以管理所有的商业物流

假设我有一个
水壶
对象,它上面有一些属性,例如
.color
.Material

但如果格兰菲迪啤酒厂想在这块土地上拥有另一处地产,该怎么办?e、 g.
.Size
和其他一些啤酒厂并不关心上述所有内容,只对
.Content
感兴趣

在OOP中,是否有一种方法可以根据名为
Customer
的某些参数使我的
Kettle
对象动态(具有不同的属性和方法)


如果我没弄错的话,这和Polymorphsim有很大的不同。

首先感谢你让我为你的英国例子发笑:-D

我要做的是,记住我是一个初学者,拥有一个处理所有属性的域对象,以及一个派生类型,它还提供一个接口来告诉租户允许读取哪些属性

interface iKettle
{
    public getColour() : ?Colour;
}

interface iUserKettle extends iKettle
{
    public canReadColour() : bool;
}

class Kettle implements iKettle
{
    public getColour() : ?Colour
    {
        return this.colour;
    }
}

class UserKettle extends Kettle implements iUserKettle
{
    public UserKettle(....., UserKettleProperties props)
    {
        this.props = props;
    }

    public canReadColour() : bool
    {
        return this.props.canRead("colour");
    }

    public getColour() : ?Colour // override
    {
        if(this.canReadColour())
            return super.getColour();
        else
            throw new Exception("You aren't allowed to know the colour");
    }
}
canRead*方法的要点是有一个明确的方法来知道属性是否可读

假设您有一个cattle字段,它返回一个值,并且也可以为null。 然后执行instance.getSomeProperty()并得到NULL。但是你得到NULL是因为这个值实际上是NULL还是因为你不允许读取它?这就是为什么您有第二个方法canReadSomeProperty(),它告诉您是否允许调用getter方法


可选地拥有CANRead *方法和抛出异常,您可以考虑只返回NULL或NULL对象。

< P>如果这些属性是动态的,那么您有几个选项。

  • 拥有具有公共属性的基类,然后派生具有已定义新属性的新类。 但是,此解决方案有一个问题-您必须为每个需要特殊属性的客户创建不同的构建。 另外,系统在代码级别上的显式属性的意义上是完全文档化的

  • 属性建模为单独的自治类,并能够创建属性实例,并在运行时将其分配给域对象。 属性可以在DB中定义(使用它们的名称,可能是数据类型),然后分配给需要的特定域类。这样就不需要为每个不同的配置创建新的构建,只需要更新数据库

  • 这个简单的类图展示了以下思想:


    附加属性在数据库中定义,而不是在运行时读取中定义,并分配给域对象

    在这个场景中,您不能应用太多DDD,因为域概念的定义会从一个客户端更改到另一个客户端。我的意思是,我们都有一个水壶,但可以有客户想要的任何财产。你如何运用行为?更确切地说是关于什么

    最多您的“域”对象将是数据结构。在定义对象时谁有发言权以及自定义选项是什么都很重要。例如,如果客户机可以从预定义的属性中进行选择,那么您就有一些回旋余地

    但是,如果他们可以添加任何名称的属性,您就失去了语义,只会得到由神奇字符串组成的数据结构。您不能强制执行业务规则,除非您还有一个业务规则编辑器,客户端可以使用它来定义规则。这对开发者和客户来说都是相当复杂的


    因此,在我看来,DDD并不真正适用于此,除非您为每个客户构建单独的应用程序,但适当的OOP仍然适用。不过,您将使用数据结构,ORM可能会有所帮助。

    听起来您只需要用户定义的自定义属性:

    public class Kettle
    {
        public Dictionary<string, string> CustomProperties;
    }
    
    
    var kettle = new Kettle();
    kettle.CustomProperties["Size"] = "1";
    kettle.CustomProperties["Content"] = "Some Content";
    kettle.CustomProperties["DateFermentationStarted"] = "1/1/2014";
    
    公共级水壶
    {
    公共属性;
    }
    var水壶=新水壶();
    釜。自定义属性[“大小”]=“1”;
    Ketter.CustomProperties[“内容”]=“某些内容”;
    釜.定制属性[“DateFernationStarted”]=“2014年1月1日”;
    
    您可以将这些属性作为单个客户的键/值对保存在数据库中。然后创建一个配置GUI或XML配置文件来定义每个安装的自定义属性。当您在系统中创建一个Kettle对象时,您还将从您选择的存储库中加载自定义属性


    这里的挑战是客户是否需要附加到这些属性的业务逻辑。由于属性是动态的,那么业务逻辑也需要是动态的(即插件、脚本等)。这就涉及到一系列完全不同的问题。

    谷歌多租户或多租户应用程序(只有特定租户内的用户才能使用该租户内的对象)。再看看沃恩·弗农的书《谢谢麦克斯》。谷歌返回的很多信息似乎暗示我“为每个客户创建不同的应用程序”。。真的没有更好的办法吗/多租户应用程序允许您在同一应用程序中瞄准多种类型的啤酒厂。似乎谷歌没有返回正确的结果;-)您可能缺少一个概念,即表示水壶是什么的定义(例如,它具有什么属性)的抽象。现在,这无数的动态属性回避了一个问题:行为在哪里,以及为什么/如何受到这些动态属性的影响。“面向客户构建”是一种不成熟领域或你所知甚少领域的味道。在任何情况下,如果您还想在操作端扩展此功能(更多部署),则需要挖掘仍然为客户提供价值的通用抽象。我很高兴您发现示例场景很有趣:D您所建议的假设是