8
class Book {
    private Chapter[] chapters = new Chapter[5];
 }

class Chapter {
    private Book book;
}

Relationship

Is this the correct way to implement the above relationship? I need explanation on this. Thanks.

Gholamali Irani
  • 4,391
  • 6
  • 28
  • 59
swei
  • 83
  • 1
  • 6
  • a Book has Chapters, the way you wrote it, is that the Chapter also has a Book. remove that line – Stultuske Jan 19 '18 at 09:56
  • A book can have Chapters... chapters having a book is weird... so remove the cyclic reference to a book in the Chapter class... – ΦXocę 웃 Пepeúpa ツ Jan 19 '18 at 09:57
  • remove the Book book object inside Chapter class..and it is okay now... – ArifMustafa Jan 19 '18 at 09:57
  • https://stackoverflow.com/questions/11881552/implementation-difference-between-aggregation-and-composition-in-java – Varvarigos Emmanouil Jan 19 '18 at 09:58
  • 2
    There seems to be some confusion here: composition means that the chapters are always part of one book and when you delete the book you delete the chapters as well. Your code right now could be a composition or it could be an aggregation, I can't tell due to the missing details. The chapters having a back reference isn't a problem though, it still can be a composition that way - it depends on how you set that reference. For a composition you need to make sure that only the book that references the chapters can be set as a chapter's book reference. – Thomas Jan 19 '18 at 10:06
  • 3
    To expand on my comment: since the diagram you posted doesn't contain an arrow it's perfectly fine for the chapter to have a reference to the book it belongs to. Would it look like `[Book]♦--->[Chapter]` _that_ would mean you can't have that back reference. – Thomas Jan 19 '18 at 10:17
  • @Thomas and what would happen if that Book inside Chapter was instantiated? – Stultuske Jan 19 '18 at 10:20
  • 1
    The Java syntax for declaration of associations, aggregations and compositions is identical: it's just one object having a field that is a reference to another object. The only thing that differentiates them is how you use those fields throughout the code, after they are declared. In your Book class, the `chapters` field denotes composition. In your Chapter class, the `book` field denotes just an association. That's perfectly fine. Though I'd suggest making the `book` field final, since a chapter can never change the book it belongs to. – DodgyCodeException Jan 19 '18 at 10:23
  • @Stultuske as long as book and chapters have the same lifecycle it would still be a composition but implementing it that way would at least be odd and would make me wonder if the model was implemented correctly. – Thomas Jan 19 '18 at 10:23
  • @Thomas each book has chapters, within each chapter a new Book is instantiated, (which would have chapters, each having a Book, ... ) – Stultuske Jan 19 '18 at 10:27
  • 1
    @Thomas Rather to use an arrow you should use the dot notation. – qwerty_so Jan 19 '18 at 10:35
  • 1
    @Stultuske if you'd implement it that way then you'd not be doing it right. As I said, the model states what the code should do and there are various ways of implementing it. The model itself (and composition in general) does _not_ restrict you from having those back references. – Thomas Jan 19 '18 at 10:39

1 Answers1

4

That is not enough.

In Composition relationship, If whole instance is destroyed, the part instance should also be destroyed immediately.

You should have some codes (some machanisms) to do that.

For example if you push the instances of Chapters from external the class (for example by using a constructor), you should be careful to delete those instances when the Book instance is deleted.

If your instances are created within the Book class (by new ...), there is no need to do something and your Chapter instances will be deleted with Book instance.

In this reference: Object Prime, Third Edition (by Scott W. Ambler, 2004)
in section (13.4.12.7 Implementing Composition)

As you might have guessed, aggregation and composition associations are handled exactly the same way as associations. The main difference, from a programming point-of-view, is aggregation implies a tighter relationship between the two classes than association does, and composition implies an even tighter relationship still. Although Fig. 13.11 does not include composition associations, the association between Seminar and Course is tight, in fact, at least as tight as you would see with composition (unfortunately the sentence rule does not make sense in this case). In Fig. 13.31, you see the result of this closeness in the implementation of the remove() method in the Course class—when a course is removed, its seminars are also removed. This type of lifecycle management code is typical within composition hierarchies.

/**
 * Remove a course
 *
 * @postcondition The course and its seminars will be removed
 */
public void remove() 
{
  if (getSeminars() != null) {
    // Clone the original set because we can't safely remove
    // the items from the set while we iterate over it
    HashSet set = (HashSet) getSeminars().clone();
    Iterator iterator = set.iterator();
    // Remove each seminar of this course
    while (iterator.hasNext()) {
      Seminar seminar = (Seminar) iterator.next();
      // Remove the seminar from the collection
     getSeminars().remove(seminar);
    }
  }
  // Remove the instance from permanent storage
  // Persistence code ...
}


Consider this example:

class Person {
   private final Brain brain;
   Person(Brain humanBrain) {
      brain = humanBrain;
   }
}

And in other parts of code we can define like this:

Brain b = new Brain(); 
       // or we have an instance of Brain in other scopes
       // not exactly in this scope

Person p1 = new Person(b);
Person p2 = new Person(b);

So, in this code, we can set one instance of Brain to two different Persons.

Note: In composition, we should manage the life cycle of instances. Only defining a private final of any class, do not show the Composition between them.

For example the below example can be a Composition. Because instances of Part deleted when the whole is deleted:

public class House {    
   private final Room room;

   public House() {    
       room = new Room();
   }
}

In Composition:
The whole may directly be responsible for creation or destruction of the part. Or it may use a "part" that has been already created and managed from external of class (by other parts of code). In this case, deletion of part should be managed by external code and the part should be deleted immediately after the whole deletion.

We should establish a mechanism to delete part when the whole is deleted. If we do not delete the part and use it in other wholes it is Aggregation or Association.

Gholamali Irani
  • 4,391
  • 6
  • 28
  • 59
  • Assuming the Book object is what references the Chapters, the destruction of the Book object would result in garbage collection of the subsequent chapters. – christopher Jan 19 '18 at 10:03
  • If the instance pushes from external, and we have another reference in the external the class, that instance will not deleted by whole class. – Gholamali Irani Jan 19 '18 at 10:06
  • 1
    so far, we have no evidence that that is the case – Stultuske Jan 19 '18 at 10:07
  • In Object Prime, Third Edition, I will add it to my answer. – Gholamali Irani Jan 19 '18 at 10:09
  • 3
    Your first statement is wrong. The association does not forbid a two-way navigation. So you can well have `book` inside `Chapter`. – qwerty_so Jan 19 '18 at 10:31
  • @ThomasKilian, thanks, in that case, there is no need to arrow in the Chapter side? – Gholamali Irani Jan 19 '18 at 10:32
  • Don't forget that it is perfectly OK to move a chapter to another book (or have it as a standalone object of the multiplicity to Book allows it) and then delete the book without having to delete said chapter. – Geert Bellekens Jan 19 '18 at 10:36
  • Well, the OP start's from the diagram as given and he wants the implementation. If (and only if) you comment on the diagram, one should use the dot notation (since the reference does really not make sense). – qwerty_so Jan 19 '18 at 10:36
  • @GeertBellekens, if it is OK to use an instance of chapter in other books, It it Aggregation. – Gholamali Irani Jan 19 '18 at 10:37
  • 1
    @GeertBellekens When I find chapters re-used this is the last book I bought from that author :-D – qwerty_so Jan 19 '18 at 10:37
  • I did not say *use*, I said *move*. A chapter is always a part of a single book at a time, but it may move from book to book. – Geert Bellekens Jan 19 '18 at 11:42
  • @GeertBellekens For a reader/buyer that does not make a difference. – qwerty_so Jan 19 '18 at 14:11
  • @ThomasKilian I was talking about the specifics of UML compositions, not about books IRL. – Geert Bellekens Jan 19 '18 at 14:13
  • @GeertBellekens, I think that, if in our implementation we **can move** a `Chapter` instance from one `Book` instance to another `Book` instance, **so** in deleting a `Book` instance we can move `Chapter` instances to another too. Therefor that can not be a Composition implementation. But, if in deleting a `Book` instance, we delete all `Chapter` instances too (and do not move them to another classes) it can be Composition implementation. – Gholamali Irani Jan 19 '18 at 16:06
  • Yes, deleting the book should result in deleting all the chapters of the book. But there is no rule that says you can't move chapters to another book. – Geert Bellekens Jan 19 '18 at 17:28