Java 为了最大限度地重用和提高效率,正确的OO设计是什么?
假设我有一个Java包(包括.jar和源代码)。下面是一些我想重用的类的定义Java 为了最大限度地重用和提高效率,正确的OO设计是什么?,java,oop,inheritance,Java,Oop,Inheritance,假设我有一个Java包(包括.jar和源代码)。下面是一些我想重用的类的定义 abstract class Tree { public abstract Tree[] children(); public void print(); } class LabeledTree extends Tree implements Label { Label label; Tree[] daughterChildren; public Tree[] children(); } cla
abstract class Tree {
public abstract Tree[] children();
public void print();
}
class LabeledTree extends Tree implements Label {
Label label;
Tree[] daughterChildren;
public Tree[] children();
}
class Demo {
public static void main(String[] args) {
Parser p = new Parser();
String[] sent = { "This", "is", "an", "easy", "sentence", "." };
Tree parse = p.apply(sent);
parse.print();
}
}
上面的apply
方法返回一个LabeledTree
。现在,我想创建我自己类型的树,比如说MyTree
,它具有以下结构
class MyTree {
int value;
Label label;
public void myPrint();
}
你建议我把这个类放在继承树的什么地方,这样我就可以直接从
apply
方法实例化这个类的对象了?你认为我应该如何设计我的系统以最大限度地实现软件重用,而不必解析每一棵树来构建MyTree
的对象?你的谜题中缺少了一些片段,这使得我无法给出完整的答案,但是作为第一个猜测,我建议将代码泛化,作为实现泛化并允许更容易扩展的第一步 您的谜题中缺少了一些片段,这使得我无法给出完整的答案,但作为第一个猜测,我建议将您的代码泛化,作为实现泛化并允许更容易扩展的第一步 几点评论:
首先,树定义公开了一个重要的细节——每个树对象都是一个节点。这将创建一大堆概念单元。在真正的API中,您将有一个树接口和一个使用节点的实现。所有数据成员都将位于节点中,但根节点除外,根节点将位于TreeImpl中
其次,我非常相信命名是良好可读代码的关键第一步,它通常会影响OO设计的质量。
树不应该简单地实现标签。你能说:“一棵树就是一个标签”吗?
另一方面,如果您有以下情况:
“TreeNode实现了HasLabel”,这会更清楚——“您的树节点有一个标签”
第三,您遇到了众所周知的OOP一致性和差异问题。在当前设计中,标记树的根具有标签,但较低的节点(仅为树)不必是标记树。这将是有趣的调试。泛型可以帮助您解决这个问题,但请务必阅读有效的Java,以了解约束泛型类型是如何工作的。几点注释:
首先,树定义公开了一个重要的细节——每个树对象都是一个节点。这将创建一大堆概念单元。在真正的API中,您将有一个树接口和一个使用节点的实现。所有数据成员都将位于节点中,但根节点除外,根节点将位于TreeImpl中
其次,我非常相信命名是良好可读代码的关键第一步,它通常会影响OO设计的质量。
树不应该简单地实现标签。你能说:“一棵树就是一个标签”吗?
另一方面,如果您有以下情况:
“TreeNode实现了HasLabel”,这会更清楚——“您的树节点有一个标签”
第三,您遇到了众所周知的OOP一致性和差异问题。在当前设计中,标记树的根具有标签,但较低的节点(仅为树)不必是标记树。这将是有趣的调试。泛型可以帮助您解决这个问题,但请务必阅读有效的Java,以了解约束泛型类型是如何工作的。我同意@Uri的观点,将树作为接口而不是抽象类将是一种改进 若您的解析器不知道树的子类,那个么一种方法是使用Class.forName的基于反射的方案。另一种处理方法是使用一个系统,在安装扩展时在该系统中进行注册(这里的一个例子是Eclipse插件注册表,尽管它是这种模式的一个非常复杂的例子) 您更大的问题实际上是关于如何最好地组织用OO语言编写的解析器。关于这个问题有很多很多书。你可以试着看看这本书: Java编程语言处理器:编译器和解释器 大卫·瓦特(作者)、德里克·布朗(作者) 它可以在Amazon上找到,并且对开始理解如何设计语言解析器很有帮助。这些例子都是用Java编写的 此外,如果您有语法,您可以尝试通过Antlr运行它,并查看输出以获得如何组织解析器的良好示例
我同意@Uri的观点,将树作为接口而不是抽象类将是一种改进 若您的解析器不知道树的子类,那个么一种方法是使用Class.forName的基于反射的方案。另一种处理方法是使用一个系统,在安装扩展时在该系统中进行注册(这里的一个例子是Eclipse插件注册表,尽管它是这种模式的一个非常复杂的例子) 您更大的问题实际上是关于如何最好地组织用OO语言编写的解析器。关于这个问题有很多很多书。你可以试着看看这本书: Java编程语言处理器:编译器和解释器 大卫·瓦特(作者)、德里克·布朗(作者) 它可以在Amazon上找到,并且对开始理解如何设计语言解析器很有帮助。这些例子都是用Java编写的 此外,如果您有语法,您可以尝试通过Antlr运行它,并查看输出以获得如何组织解析器的良好示例
丢失了哪些零件?关于泛化,你能说得更具体些吗?我宁愿不碰软件包的代码,只添加我自己的代码。缺少哪些部分?关于泛化,你能说得更具体些吗?我宁愿不碰软件包的代码,只添加我自己的代码。