OO设计模式:如何动态添加方法?

JCv*_*mme 2 c# java oop design-patterns

我在C#(或Java,无关紧要)中实现了一个简单的树结构,其中所有内容都围绕着抽象类Node及其子类.Node提供与数学图论相关的方法和属性.例如,Node.Parent引用父节点和Node.Children子节点

class Node {  
    Node Parent;  
    Node[] Children;

    void appendNode(Node node) { ... }
}  
Run Code Online (Sandbox Code Playgroud)

我正在使用树来执行计算.计算涉及大量递归,我还需要为每个节点存储中间值.对于每个计算,我已经向Node类引入了其他属性和方法,例如

class Node {  
    Node Parent;  
    Node[] Children; 

    // Calculate weight
    int weight; // current weight
    void recalculateWeight() {
        // perform some heavily recursive stuff
        // involving Parent.recalculateWeight()
        // and update the value of the variable weight
    }

    int price; // current price 
    void recalculatePrice() {
        // perform some heavily recursive stuff
        // involving Parent.recalculatePrice()
        // and update the value of the variable price
    }

    void appendNode(Node node) {
        // ...
        recalculateWeight();
        recalculatePrice();
    }
} 
Run Code Online (Sandbox Code Playgroud)

但现在我必须放弃这种方法,因为应该动态添加计算值而不更改Node类.动态意味着其他人应该能够仅依靠Node类的"图形理论方法"在给定树上实现自己的计算.

你知道什么是一个好的设计模式吗?

dka*_*zel 6

这尖叫着访客模式.

interface Visitor{

    visit(Node node);

}

class Node{

   //...


   void accept(Visitor v){
       //feel free to change visit order to viist children first
       v.visit(this);
       for(Node child : children){
          v.visit(child);
       }

   }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以让你所有不同的计算不同的访客.创建新类型的计算或遍历根本不会改变Node类.您只需制作一个新的访客实施.

class WeightVisitor implements Visitor{

   int weight = 0;

   void visit(Node n){
        weight += ...
   }

}
Run Code Online (Sandbox Code Playgroud)

然后每次你想计算重量

WeightVisitor visitor = new WeightVisitor();

rootNode.accept(visitor);

int weight = visitor.getWeight();
Run Code Online (Sandbox Code Playgroud)