Java class that models a book

Before asking a question, I have to say that this is homework, and I'm only looking for ideas on how to implement a class that models a book.

The book has a title and many chapters, each chapter has a title and several subpatterns. Each subsection has a heading and a list of paragraphs. Each paragraph may contain a number and text. I want to implement the following functions in OOP: add / delete: chapters, subchapters and paragraphs and display a book. I'm having trouble finding the right structure for the class.

This is how I am going to implement it, but it seems redundant and complicated. Are there simpler and more correct ways to do this?

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> { } 
+5
source share
4 answers

Your first approach is very good, but does not take into account the possibility of evolution.

What happens if we ask you to add the ability for paragraphs to have 0-n quotes (or anything else)? What happens if we ask you to add a chapter to your book that cannot have a chapter?

This will require huge changes. You should take a look at the composite template .

Following this pattern, you will be more flexible in terms of evolution.

When you think OOP, you should always remember that interfaces can have a huge role in how you develop your code. Many of these problems have already been solved and have a conditional solution (design patterns). You should spend time studying the most common ones. This will definitely change your coding approach.

("Designing a Template Head First" is a good book to read).

Moreover, one of the most important features of OOP is encapsulation. This provides a very efficient way to control the accessibility of class attributes. You MUST use it. Start by adding private or protected modifiers in the attributes of your class and create the getters / setters needed to access / change these attributes.

One more note: You should not use the System.out.println() method to register your code. Use the log API (e.g. log4j) and exceptions.

  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)); } 
+5
source

This is actually not the right design. (but I like the way you think about minimal code writing)

The book is not expanded by chapter or "chapter elements." The book contains chapters, and may also contain / do something else.

Therefore, the right design is the simplest

 public class Book{ private String title; private List<Chapter> chapters; } //other classes would look similar 

This approach is much more stable and makes it easy to change (or even replace) in the future.

This โ€œphenomenonโ€ also has a name, Composition over inheritance

+3
source

Your general model actually makes a lot of sense. You have identified the duplicate code and separated it from the class. Using generics helps maintain cleanliness. Is it worth it to explicitly select the layers of the tree (for which it essentially is), since Subchapters, Chapters, etc. Depend on your exact requirements.

It may be easier to simply identify the nodes and leaves of the tree, but if you need different behavior at each level and donโ€™t need the flexibility to add or remove more layers, then this is normal. Consider, for example, if you ever have an omnibus with Omnibus-> Book-> Chapter-> Subchapter-> Paragraph or a book with a book-> Chapter-> Section-> Chapter-> Paragraph. Could your model support them? If it is not necessary?

Some names may be clearer (for example, nr as a number) or may not conform to style conventions (the name should be a heading).

The main mistake, I would say, is to save the number inside the object in general. This is fragile because it means that you constantly have to update it when things are added, deleted, etc.

You can always find out the number simply by looking at the position in the parent. In essence, you are duplicating this information.

As Grigori noted in the comments, all variables must be private and accessible through getters and setters.

+2
source

Your design is good. There are several errors in the code; I suggest writing a few unit tests to find them (hint: try to delete pages).

I wrote book processing software in several languages โ€‹โ€‹(Java, Python, Groovy) and found it to be harder than it sounds. The problem is that all the elements (book, chapter, subsection, paragraph) have many common features, but subtle differences. Most of them are containers for certain types of other elements (therefore, the book consists of a chapter, but not paragraphs). Only a paragraph is not a container. They all have text (title or paragraph text), but the semantics of the text are different. Also, do the titles for the sub-chapters make no sense, or are they?

It is very difficult to come up with a good API to handle all corner cases without too much duplicated code, especially in Java, where you don't have Impurity .

+1
source

Source: https://habr.com/ru/post/1235789/


All Articles