【问题标题】:Design of a Bot class capable of returning Answer objects for all sorts of Question objects设计一个能够为各种 Question 对象返回 Answer 对象的 Bot 类
【发布时间】:2010-02-18 01:15:32
【问题描述】:

我正在尝试构建一个 GraphBot 类,它可以回答有关关联图的不同问题,例如路径长度、两个顶点之间的最短路径、通过给定顶点的路径数等。

我希望能够在不更改 Bot 内部的任何代码的情况下添加新问题,它只负责接收问题,委托其他算法使用与 bot 关联的图形来解决问题并返回回答。

所以是这样的:

public class GraphBot {
    private Graph graph;

    public GraphBot(Graph graph) {
        this.graph = graph;
    }

    public Answer ask(Question question) {
        // delegate somehow to answer the question, providing the graph
        // return an Answer object encapsulating the answer
    }
}

public interface Answer {
    public toPrintableOutput();
}

public interface Question {
    // question methods go here... this is what I'm having trouble with
}

我遇到的问题是问题具有相关的条件或参数。例如,“A”和“B”之间的问题“路径长度”具有问题类型(“路径长度”),这是所有问题都会有的,还有参数“A”和“B”。相比之下,“通过顶点的路径”问题将只有代表顶点的参数“C”。

我想不出一种呈现统一界面的方式,以便系统可以轻松扩展以处理具有不同数量和类型参数的众多不同问题。我可以有一个与每个问题相关联的 QuestionSolver 在这种情况下,如果每个 Question 具有不同的属性并不重要,因为 QuestionSolver 可以断言问题是有效类型,但这需要在某处将 Question 映射到 QuestionSolver每当引入新问题时都需要更新。

实现这个系统的最可扩展的方式是什么,以便新问题不需要对不同类的负载进行大量更改?我真的希望能够创建一个实现 Question 的类,并可能创建一个可以解决该问题的类,然后让 GraphBot 能够自动处理该问题。

【问题讨论】:

    标签: oop architecture


    【解决方案1】:

    您可以做的只是让ask() 方法成为Question 接口的一部分,并采用Graph。这样一来,每个Question 都必须知道如何回答自己,而您不必设计一个未来可扩展的Question api。

    编辑:为什么这比让GraphBot 能够回答Question 更好?

    • 简单性:正如您所发现的,设计一个Question API 将考虑任何问题所需的所有可能数据以及弄清楚如何将其编译成动态提问算法是非常困难的。为每个 Question 编写自定义代码要简单得多,它知道如何处理公开的 Graph 数据。
    • 依赖关系:您的初始方法使相对稳定的GraphBot 依赖于绝对不稳定的Question。我的方法扭转了这种依赖关系,使它变得更加简单,这又回到了最后一点。
    • 维护:我保证您无法预测Question 类需要提供的所有内容。当(不是如果)您遇到需要在Question 接口中进行的更改时,每个 实现者都需要进行更改。如果有多个Question 实施者,这将使您(或其他开发人员)以一千个太阳的炽热热情讨厌您的未来。

    最后,我想不出一个令人信服的理由不自己回答问题。是的,有争议的是,从纯粹抽象的“这是否与现实世界一致”的角度来看,这并没有多大意义,但是对于一个问题来处理它自己的答案,这既实用又不是不合理的。关于 OOP 要记住的一件事是,与现实世界的相似之处是为了方便,而不是作为规则。不要让自己被他们束缚。

    所以现在应该是这样的:

    public class GraphBot {
        private Graph graph;
    
        public GraphBot(Graph graph) {
            this.graph = graph;
        }
    
        public Answer ask(Question question) {
            return question.ask(graph);
        }
    }
    
    public interface Answer {
        public toPrintableOutput();
    }
    
    public interface Question {
        public Answer ask(Graph graph);
    }
    

    【讨论】:

    • 这样的设计是不是很好——让一个问题知道如何回答自己有意义吗?
    • 一个问题知道如何回答自己是非常有意义的。如果它不知道,谁会?
    • 这看起来确实很简洁,意味着只实施 Question 来扩展系统,但仍然感觉必须向某事/某人提出问题,然后他们才能回答,而不是能够问质疑自己的答案。我知道这很挑剔,但我只是想了解面向对象的设计。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2014-10-15
    • 2022-07-27
    • 1970-01-01
    相关资源
    最近更新 更多