Hm. Ich verstehe is-a und has-a völlig anders.
is-a bezieht sich rein auf Vererbungsbeziehungen. Die sollten nicht zu ausufernd sein. Du wirst auch bei komplexen Frameworks selten mehr als 2 Vererbungsebenen unterhalb einer abstrakten Klasse sehen.
Es ist allerdings schon richtig, das man in OO mehr dazu neigt, die Datenstrukturen im Hinblick auf die Menge der Attribute zu verkleinern. Das hat gute Chancen die Übersichtlichkeit zu erhöhen.
In Java würd ich history immer in einer eigenen Klasse definieren und diese Klasse dann irgendwo als Attribut in eine eigene Klasse hängen. Das ist has-a. BUT: Wenn ich die history als zusätliche Attribute in andere Objekte schreiben würde, ohne dass sie durch eine eigene Klasse "zusammengehalten" würden, dann ist das NICHT is-a.
In OO kann man Daten problemlos in so viele Teile zerstückeln wie einem das sinnvoll erscheint. Es existieren keine merklichen physischen Kosten. Objekte leben im Arbeitsspeicher.
Eine Operation
myObj.getHistory().getSubject();
heißt in Java nichts anderes als:
Suche die Speicheradresse, die in dem Property history von myObj gespeichert ist.
Suche dort die Speicheradresse des property subject und gebe dieses zurück (es ist ein Objekt vom Typ java.lang.String)
Im Arbeitsspeicher läuft das alles rasend schnell.
Es beansprucht vom Rechner nicht viel mehr Arbeit als:
myObj.getHistorySubject();
Hier spart man die Suche der Speicheradresse des Objekts des Typs History. Diese Operation ist aber nicht kostspielig.
Das sieht anders aus, wenn man sich wie in Notes die Daten erstmal von Platte holt. Da bedeutet die Suche und das Lesen von history (also der Zwischenschritt) deutlich kostspieligere IO Operationen.
Heute abend folgt noch eine Anekdote, warum das in RDBMS Sinn machen könnte, die History in einer eigenen Tabelle abzuspeichern. RDBMS ist aber nicht OO.
Design Pattern Bücher enthalten keine Regeln, wie man zu programmieren hat. Patterns sind solutions in a context. Dies drückt bereits aus, dass die Anwendung eines Patterns oder einer Design-Best-Practice wie has-a oft besser als is-a immer eben auch kontextabhängig ist.
Aber wie gesagt: Mit is-a hat das ganze null zu tun.