在尝试使复合 class 方法对另一个包 class 可见时避免破坏 SOLID 原则

Avoiding breaking the SOLID principles while tryning to make a composite class methods visibile to another package class

我正在为我的 java 考试准备一个大学项目,该项目包括创建路由器网络并相互发送数据包,直到数据包沿着最短路径到达目的地。

这个项目要求坚持SOLID原则,我其实是处于停滞状态,可能是第一次接触java。

我创建了一个 NODE class 代表通用网络节点,它只负责保存与 IP 关联的名称,没有其他责任,然后我创建了一个 ROUTING class,它是责任是将所有已知的网络路由保存在 HashMap<Node,integer> 中(整数表示流量负载,它是随机的)包括使用方法显示和添加条目到地图。

节点 class 将路由 class 作为受保护的内部 class 对象。

现在这些 classes 存储在 ROUTER 包中,为了创建网络,我创建了另一个名为 NETWORKSTARTER 的包和一个名为 STARTER 的 class,这个 class目的是创建一个网络并将网络的其他实体相互连接(将节点添加到路由器 table)。

当我编写连接方法时,我偶然发现我无法调用 NODE.ROUTING 的内部方法,即使它是 NODE class 中的受保护 class .

试图解决这个挫折我想过在 NODE class 中创建三个方法 "wraps" ROUTING class 的方法,基本上用其他名称调用它们,这个STARTER 方法可以通过 NODE 方法调用 ROUTING 方法以将节点添加到 HashMap。

问题是这样的:这个设计是否违反了SOLID原则?尤其是NODEclass设计是否违反了单一职责原则?

public class NODE{
private String nodeName;
private int nodeIP;
protected ROUTING nodeRoutingModule;

public NODE(String x,int y){
this.nodeName=x;
this.nodeIP=y;
this.nodeRoutingModule = new ROUTING();
}

// setter and getters for name and IP

public void addRoute(NODE node){
    this.nodeRoutingModule.addToMap(node);
}

public void showTable(){
    this.nodeRoutingMdoule.showMap();
}

}
public class ROUTING{
private HashMap<NODE,Integer> routeTable;

public ROUTING(){
    this.routeTable = new HashMap<>();
}

public void addToMap(Node node){
    int load = ThreadLocalRandom.current().nextInt(0,11);
    routeTable.put(node,load);
}

public void showMap(){
    routeTAble.forEach.((t,u) -> {
        system.out.println(t.getIp+" "+t.getName);
    });
}

}

public class STARTER{
private LinkedList<NODE> nodeCollection;

public STARTER(){
    this.nodeCollection = new LinkedList<>();
}

// here I populate the list with NODES

public void connectNodes(){
    // logic with a forEach cycle calling for each node
    // the method to add the node to his routing table with
    // another inner forEach cycle using the NODE class
    // wrapping the ROUTING methods
}

这将取决于您的职责:)

让我们从另一个地方开始。让我们从您的模型开始吧。

当你说 NODE 时我有点困惑,但你的意思是 ROUTER。我知道它确实是网络中使用的术语,但您仍然在创建模型。

我知道这似乎有点愚蠢,但想一想并专注于您使用的语言

  • 一个ROUTER的职责是什么?

VS

  • 一个NODE的职责是什么?

NODE 的职责是什么?好吧,NODE 是一个通用术语,用于表示图、树、网络或其他任何元素的一部分。

现在 ROUTER 是另一回事了。 ROUTER确实是NETWORK中的NODE它也是routes/sends 数据包到网络中的其他 ROUTERS

它还与网络中的其他节点通信(通过发送消息,这是关键)以计算ROUTING TABLE。 То 计算 ROUTING TABLENODES 使用 PROTOCOLLink state, Distant vector 等)

如果您正在制作真实的网络模型,您应该考虑这些因素。

现在到 NetworkStarter。你是建立网络还是 connect/assemle 网络?另外,为什么网络会开始保存节点列表?在我看来,它的责任是 connect/assemble 网络。

之后,构建 ROUTING TABLE 的责任在节点上。

现在来个概念ROUTE

什么是 ROUTE?好吧,这是两个或更多 NODES 之间的路径。让我们在网络中的邻居之间添加另一个概念:CONNECTION(图中的EDGE)。

让我们写下到目前为止的所有概念

  • Router - 职责:发送数据包,构建路由 table
  • RoutingTable - 由 Router 使用,职责:存储路由(或路径)
  • Connection - 从一个路由器到另一个路由器的连接
  • ConnectionsTable - Router 使用 职责:商店邻居
  • Path - 两个或多个节点之间的路径
  • Node - RouterNode
  • NetworkAssembler - 职责:Assemble 网络,连接路由器(节点)
  • Routing Protocol - 路由器用来通信和计算RoutingTable

现在到 SOLID:

单一职责:这是一个棘手的问题!

有时一个组件(可以是一个对象)有不止一个职责。在内部,它可能由其他 thingscomponents 组成,可能只有一个职责。

Router 为例。它的单一职责是什么?在现实世界中,事情不像在软件中那样工作。您不能只让网络负责在现实世界中构建路由 table。网络不像路由器那样作为物理存在,它们是由 组件组成的。

我们已经研究了职责并将它们分配给不同的概念。

Open-Closed:

扩展我们的系统意味着什么?

  • 添加模式节点?是的,这是可以做到的,这就是网络设计背后的全部理念:)

  • 更改协议?使用新 protocols 向路由器添加扩展能力(并配置要使用的协议):提示使用 STRATEGY PATTERN 实现

  • 重新排序网络?您使 NetworkAssembler 可扩展(使用策略模式或其他方式)。在现实世界中,您会派系统管理员参加课程以学习更多知识。这就像注入了一种新的策略模式:)

Liskov 替换原则:如果您使用策略模式,请确保您不会过多地泄漏抽象

界面隔离:为您的概念使用小界面(RouterRoutingProtocol 等)

依赖倒置:使用接口并使它们变小:)

我不会提供任何代码示例,因为人们确实通过编程来学习如何编程,因为这是您的任务 :) 使用此答案中的内容确实可以推导出您的概念,将它们捕获到代码中并进行良好的实现。

祝你好运,编码愉快:)