当成员也是分层结构时,如何构建类结构?

Posted

技术标签:

【中文标题】当成员也是分层结构时,如何构建类结构?【英文标题】:How to build a class structure, when members are also structured hierarchically? 【发布时间】:2016-05-26 17:09:15 【问题描述】:

我正在构建一个 php Web 应用程序,该应用程序应该为用户提供一种在他与另一个人/组织之间订购“安装”/设置(ConnectDirect 或文件传输网关)连接的可能性。

(连接实现的技术规范并不重要——在应用程序中它只是关于连接作为产品,可以订购和管理。)

其模型层的类层次结构应代表以下现实世界的基础设施:

连接,可以订购。 连接可以是 IBM Connect:Direct 连接或 IBM File Transfer Gateway 连接。 CD 连接直接从 A (source) 到 B (target)。 FTGW 连接物理上 由两个连接组成:A(源)到 FTGW 服务器和从 FTGW 服务器到 B(目标)——但是 逻辑上(对于订购用户)它也是一个连接。 (另外还有一个 FTGW 连接的情况,它使用 Connect:Direct 作为 protokoll。) 每个端点要么是源,要么是目标。

所以我看到以下逻辑元素:逻辑连接物理连接角色来源target), connection type, order, endpoint, endpoint type (CD and FTGW) .

我目前的结构是这样的:

但是有一些问题:

    两个层次结构树,其中一个组成的每个元素都包含特定子集的元素另一个(每个 CD 连接由 CD 端点组成;每个 FTGW 连接由两个 FTGW 端点组成,或更准确地说:每个 FTGW 逻辑连接由两个物理 FTGW 连接组成——每个都由一个 FTGW 端点和 FTGW 服务器组成作为第二个端点)。

    另一种方法可能是将EndpointPsysicalConnection 之间的关系替换为两个关系:EndpointCD-PsysicalConnectionCDEndpointFTGW-PsysicalConnectionFTGW

专业版:更一致;消除了从一对任意端点构建每个连接(类型)的伪造可能性的逻辑不精确性(甚至可能错误)。 相反:实际上,包含两个端点的要求是每个心理连接的一个特征——从这个角度来看,这是非常基本的PsysicalConnection 类。

    每个端点都可以是源和目标,并且包含不仅有公共端点属性,还源和目标属性。这意味着,根据端点的当前角色,某些属性是浪费。这也会影响数据库结构(列,sometimes 必须设置,sometimes 必须bi NULL)。

    另一种方法是扩展层次结构...

    一个。 ...通过像EndpointSourceEndpoitTarget 这样的类直接从Endpoint 继承并由EndpointCDEndpointFTGW 类继承(这意味着:两个相同的子树——在EndpointSource 和@987654336 下@);

    b. ...通过类如EndpointCDSourceEndpointCDTarget(继承自类EndpointCD)和EndpointFTGWSourceEndpointFTGWTarget(继承自类EndpointFTGW)分别由具体的CD 或FTGW 端点类继承(这意味着:两次相同的子树);

    c。 ...通过像MyConcreteEndpoint***SourceMyConcreteEndpoint***Target 这样的类从具体端点类继承(这意味着:每个MyConcreteEndpoint 类都变成抽象类并获得两个子类——MyConcreteEndpoint***SourceMyConcreteEndpoint***Target,例如EndpointCDLinux 现在是抽象并被EndpointCDLinuxSourceEndpointCDLinuxTarget继承)。

    Pro:消除浪费的特性。 Contra:一个(更)复杂的类层次结构。

嗯,这是关于软件架构的,应该(当然也会)是我的设计决定。但是很高兴听到/阅读一些专家(或非专家)的想法,如何处理这种情况。像我所描述的那样,为基础架构组织逻辑项的正确方法是什么?

【问题讨论】:

赏金表明您正在寻找来自可靠和/或官方来源的答案,但是如果没有一定程度的意见或偏见,这可能很难实现。另外,这是对系统设计/架构的很长的描述,我想知道如果你把它分解成更容易消化的单独问题,这样的问答格式可能会更好。 @inki 谢谢你的评论。是的,赏金建议“来自可靠和/或官方来源的答案”实际上可能有点令人困惑。我根本没有找到更好/更合适的选择。关于将问题分解为更少的问题:当然,我通常会尝试以某种方式提问(遵循“single responsibility principle”之类的内容)。但是在这种情况下,我不知道如何缩短问题 - 它很长,但它的所有内容都是它的描述和对问题的一些想法。 您是否尝试从另一端开始建模?我在这里只看到数据。它是干什么用的? 行为用例在哪里?还是您只需要从数据直接映射到某些对象(这没什么用)? 哇。我知道我会怎么做——但即使有十年作为中间件解决方案架构师的经验,除了个人喜好,我不会把我对这些对象的建模称为任何东西。坦率地说,我会回避在 PHP 中对如此复杂的结构进行建模。虽然我可能会确保我的 PHP 对象反映了在某些后端应用程序中设计的结构。 在我看来,您正在尝试对硬件细节进行建模,使其过于接近类层次结构之类的东西。也许您应该尝试从特定域逻辑的实际 concreate 细节中抽象出您的类层次结构。最终结构当然会包含您定义的类似 concrete 类。但不是构建 2+ 个并行层次结构,而是使用诸如接口、构建器和工厂之类的东西来管理、构建和验证可能的配置,而层次结构并不“用钉子”绑定到域逻辑。 【参考方案1】:

也许我想多了,但我建议你使用稍微不同的模型来反映你的业务逻辑。

以下可能完全是误解,但我会试一试。

所以:

根据任何连接的实际情况,这里有一个概念:

每个连接都是节点的集合,数据应该经过这些节点才能到达目的地。 每个节点都可以使用特定协议与下一个节点连接,该协议仅适用于两个特定节点之间的直接连接。 协议有自己的属性,源节点和目标节点共有

基于此,我建议以下模型构建、管理和存储产品配置:

这里:

LogicalConnection 是对实际连接、节点和协议类的构建组合的引用

Connection 包含一个节点的双链表,这些节点按数据流的顺序组成。即:第一个元素是源节点,第二个是它的目标,依此类推。

具体节点包含平台特定配置、对目标 (*Node)、源节点 (*Node) 和具体协议 (*Protocol) 的引用

Protocol 包含其对源和目标的具体配置,Node 实例可以参考 Protocol 实例来提取所需的配置。

目标和源节点通过双链表结构“看到”彼此和源-目标协议配置。

Configurations\*ConfigBuilder 实现编排从 UI 接受数据并根据情况将其转换为连接、节点和协议的实际组合的过程。

IBM\ConnectDirect\ 和 IBM\FTGW\ 命名空间包含 Protocol 和 *Node 的具体实现(例如 WindowsNode、UnixNode)

如果节点或协议仍然需要包含源和目标相关属性,并且在某些配置中它们的一部分仍然可能为 NULL - 如果对未使用的列有任何顾虑,我建议对 DB 使用 EAV 存储模型等等。

使用您在问题中描述的建议模型连接可以表示如下:

Connection:IBM_CD 
  nodes:[
    //LinuxNode
      target:*nextElement,
      protocol://IBM.ConnectDirect.Protocol
        ..target attributes..
        ..source attributes..
      
      ..platform specific attributes..
    ,
    //WindowsShareNode
      target:*nil,
      protocol:
        //IBM.ConnectDirect.Protocol(same instance or null)
      
      ..platform specific attributes..
    ,
  ]


Connection:IBM_FTGW 
  nodes:[
    //LinuxNode
      target:*nextElement,
      source:*nil,
      protocol://IBM.FTGW.Protocol
        ..target attributes..
        ..source attributes..
      
      ..platform specific attributes..
    ,
    //IntermediateServerLinuxNode
      target:*nextElement,
      source:*prevElement,
      protocol://IBM.FTGW.Protocol
        ..target attributes..
        ..source attributes..
      ,
      ..platform specific attributes
    ,
    //WindowsShareNode
      target:*nil,
      source:*prevElement,
      protocol:*nil,
      ..platform specific attributes..
    
  ]
 

【讨论】:

以上是关于当成员也是分层结构时,如何构建类结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用分层子查询构建层次结构路径

大数据BI学习工具tableau第四期:构建图表之分层和分组,集

这种分层类结构的合适设计模式是啥?

从Discuz!NT项目文件结构看如何给系统框架分层和类库分文件夹

如何针对分层对象列表动态构建和存储复杂的 linq 查询?

14、分层聚类:结构化区域与非结构化区域