用于为书籍建模的Java类

J. *_*Doe 5 java oop inheritance arraylist

在提出这个问题之前,我必须说这是家庭作业,我只是在寻找如何实现一个模拟一本书的课程的想法.

一本书有一个标题和许多章节,每一章都有一个标题和多个子章节.每个子章节都有一个标题和一个段落列表.每个段落都可以有一个数字和一个文本.我希望在OOP中实现以下功能:添加/删除:章节,子章节和段落并显示本书.我在为班级找到正确的结构时遇到了一些麻烦.

这就是我想要实现它的方式,但它似乎有点多余和复杂.有更简单,更正确的方法吗?

public class Element<T> {
        int nr;
        String Title;
        ArrayList<T> x = new ArrayList<T>();

        Element() {
            nr = 0;
            Title = "";
        }

        public void removeFromElement(int index) {
            if (index <= 0 && index > x.size())
                System.out.println("The chapter doesn't exist");
            else {
                x.remove(index);
                System.out.println("Succesful deletion");
            }
        }

        public void addToElement(T elem) {
            x.add(elem);
        }
    }

    public class Paragraph {
    int nr;
    String text;
    }

    public class Subchapter extends Element<Paragraph> {
    }

    public class Chapter extends Element<Subchapter> {
    }

    public class Book extends Element<Chapter> {
    }
Run Code Online (Sandbox Code Playgroud)

Gré*_*mer 5

你的第一种方法很不错,但没有考虑进化的可能性.

如果我们要求您添加段落具有0-n引号(或其他任何内容)的可能性,会发生什么?如果我们要求您在您的书中添加一个不能包含子章节的章节,会发生什么?

这将需要巨大的变化.你应该看看复合模式.

遵循这种模式,就变革而言,你将更加灵活.

当您考虑OOP时,必须始终牢记接口可以在您设计代码的方式中发挥重要作用.许多这些问题已经解决并具有常规解决方案(设计模式).你应该花时间学习最常见的.它肯定会改变你的编码方式.

("首先设计模式头"将是一本很好的书).

此外,OOP最重要的特性之一是封装.这提供了一种非常强大的方法来控制类的"属性"可访问性.你必须使用它.首先在类的属性上添加privateprotected修饰符,然后创建访问/修改这些属性所需的getters/setter.

需要注意的另一件事是:您不应该使用该System.out.println()方法来记录您的代码.使用日志API(例如log4j)和异常.

    public void removeFromElement(int index) throws ChapterNotFoundException{
        if (index <= 0 && index > x.size()){
            throw new ChapterNotFoundException(String.format("Chapter %s does not exist", index));
        }

        x.remove(index);
        logger.info(String.format("Chapter %s has been removed", index));
    }
Run Code Online (Sandbox Code Playgroud)


Tim*_*m B 2

您的整体模型实际上很有意义。您已经识别出重复的代码并将其分成一个类。使用泛型有助于保持简洁。是否值得将树的各层明确分离为子章节、章节等取决于您的具体要求。

\n\n

仅定义树节点和叶子可能会更简单,但如果您确实需要在每一层有不同的行为并且不需要灵活地添加或删除更多层,那么这很好。例如,考虑一下您是否拥有一本包含 Omnibus->Book->Chapter->Subchapter->Paragraph 的综合集,或者一本包含 Book->Chapter->Section->Subchapter->Paragraph 的书。你的模型可以支持这些吗?如果不需要的话还需要吗?

\n\n

某些命名可能更清晰(例如 nr 作为数字)或不遵循样式约定(标题应为标题)。

\n\n

我想说的主要错误是将数字存储在对象内。这是脆弱的,因为这意味着您必须在添加、删除内容等时不断更新它。

\n\n

您只需查看父级中的位置即可随时找到该数字。本质上,您是在复制该信息。

\n\n

正如 Gr\xc3\xa9gory 在评论中指出的那样,所有变量都应该是私有的,并通过 getter 和 setter 访问。

\n