Object-Oriented Programming Foundations
Composition and Object Relationships
আপনি একটি free preview lesson দেখছেন।
Lesson Overview
এখন পর্যন্ত Enrollment class-এ আমরা learner এবং course information String হিসেবে রেখেছি।
public class Enrollment {
private String learnerName;
private String courseTitle;
private int completedLessons;
private int totalLessons;
}
এই design ছোট example-এর জন্য কাজ করে।
কিন্তু বাস্তব application-এ একটি learner-এর শুধু name থাকে না।
তার থাকতে পারে:
Learner ID
Name
Email
Account status
একটি course-এরও শুধু title থাকে না।
তার থাকতে পারে:
Course code
Title
Price
Publication status
Lesson count
যদি Enrollment class learner এবং course-এর সব information duplicate করে, তাহলে একই data multiple জায়গায় থাকবে।
Better design:
public class Enrollment {
private Learner learner;
private Course course;
}
এখন Enrollment একটি Learner এবং একটি Course object-এর সঙ্গে relationship রাখে।
এটিই object composition এবং association-এর foundation।
Learning Objectives
এই lesson শেষ করার পর আপনি পারবেন:
- একটি object-এর field হিসেবে অন্য object ব্যবহার করতে
has-arelationship explain করতে- Association এবং composition-এর basic difference বুঝতে
- Duplicate state identify এবং remove করতে
Learner,Course, এবংEnrollment-এর responsibilities আলাদা করতে- Object references constructor-এর মাধ্যমে pass করতে
- Nested object state access করতে
- Object ownership এবং lifecycle নিয়ে basic reasoning করতে
- Composition এবং inheritance-এর পার্থক্য বুঝতে
- Object relationships design করার common mistakes avoid করতে
Why Relationships Matter
একটি learning platform-এ concepts isolated নয়।
Examples:
A Learner enrolls in a Course
A Course contains Lessons
An Enrollment belongs to a Learner
An Enrollment tracks progress for a Course
Java-তে একটি object অন্য object-এর reference field হিসেবে রাখতে পারে।
private Learner learner;
private Course course;
এতে objects collaborate করতে পারে।
A First Learner Class
public class Learner {
private final long id;
private final String name;
private final String email;
public Learner(
long id,
String name,
String email
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Learner ID must be positive."
);
}
if (
name == null
|| name.isBlank()
) {
throw new IllegalArgumentException(
"Learner name is required."
);
}
if (
email == null
|| email.isBlank()
) {
throw new IllegalArgumentException(
"Learner email is required."
);
}
this.id = id;
this.name = name.strip();
this.email = email.strip();
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
এই class learner-related state own করে।
A First Course Class
public class Course {
private final String code;
private final String title;
private final int totalLessons;
private boolean published;
public Course(
String code,
String title,
int totalLessons
) {
if (
code == null
|| code.isBlank()
) {
throw new IllegalArgumentException(
"Course code is required."
);
}
if (
title == null
|| title.isBlank()
) {
throw new IllegalArgumentException(
"Course title is required."
);
}
if (totalLessons <= 0) {
throw new IllegalArgumentException(
"Total lessons must be greater than zero."
);
}
this.code =
code.strip()
.toUpperCase();
this.title =
title.strip();
this.totalLessons =
totalLessons;
this.published = false;
}
public boolean publish() {
if (published) {
return false;
}
published = true;
return true;
}
public String getCode() {
return code;
}
public String getTitle() {
return title;
}
public int getTotalLessons() {
return totalLessons;
}
public boolean isPublished() {
return published;
}
}
এই class course-related state এবং behavior own করে।
The Duplication Problem
Weak Enrollment design:
public class Enrollment {
private long learnerId;
private String learnerName;
private String learnerEmail;
private String courseCode;
private String courseTitle;
private int totalLessons;
private int completedLessons;
}
Problems:
- Learner data duplicate হচ্ছে
- Course data duplicate হচ্ছে
- Learner name change হলে enrollment stale হতে পারে
- Course title change হলে enrollment old title ধরে রাখতে পারে
- Validation repeat হয়
- Responsibility unclear হয়
Example:
Learner object:
name = Nur
Enrollment object:
learnerName = Nuur
কোন value correct?
Duplicate state consistency problem তৈরি করে।
Referencing Objects Instead of Copying Their Data
Better design:
public class Enrollment {
private final Learner learner;
private final Course course;
private int completedLessons;
private boolean active;
}
এখন:
Learner object owns learner information
Course object owns course information
Enrollment owns relationship-specific state
Relationship-specific state:
Completed lessons
Enrollment status
Enrollment date
Completion status
Constructor with Object References
public Enrollment(
Learner learner,
Course course
) {
if (learner == null) {
throw new IllegalArgumentException(
"Learner is required."
);
}
if (course == null) {
throw new IllegalArgumentException(
"Course is required."
);
}
if (!course.isPublished()) {
throw new IllegalArgumentException(
"Cannot enroll in an unpublished course."
);
}
this.learner = learner;
this.course = course;
this.completedLessons = 0;
this.active = true;
}
Constructor receives actual objects।
Usage:
Learner nur =
new Learner(
1L,
"Nur",
"nur@example.com"
);
Course javaCourse =
new Course(
"JAVA",
"Java and OOP Foundation",
20
);
javaCourse.publish();
Enrollment enrollment =
new Enrollment(
nur,
javaCourse
);
has-a Relationship
Enrollment has a Learner।
private final Learner learner;
Enrollment has a Course।
private final Course course;
এই ধরনের relationship-কে সাধারণভাবে has-a relationship বলা হয়।
Examples:
Course has Lessons
Order has OrderItems
Invoice has LineItems
Enrollment has Learner and Course references
Association
Association হলো দুইটি independent objects-এর relationship।
Example:
Learner ↔ Enrollment
Course ↔ Enrollment
Learner enrollment ছাড়া exist করতে পারে।
Course enrollment ছাড়া exist করতে পারে।
Enrollment learner এবং course-কে connect করে।
এই relationship association হিসেবে দেখা যায়।
Composition
Composition একটি stronger ownership relationship।
Example:
Course contains Lessons
Order contains OrderItems
যদি parent object-এর lifecycle-এর সঙ্গে child object tightly bound হয়, composition natural হতে পারে।
Conceptual example:
public class Course {
private List<Lesson> lessons;
}
Course lesson objects-এর organization এবং ownership control করতে পারে।
তবে composition মানেই child object অবশ্যই memory থেকে destroy হবে—Java language এমন automatic business rule enforce করে না।
Composition একটি design relationship।
Aggregation
Aggregation composition-এর চেয়ে weaker ownership relationship হিসেবে describe করা হয়।
Example:
Team has Engineers
Department has Employees
Engineer team change করতে পারে এবং independentভাবে exist করে।
Practical Java code-এ association, aggregation, এবং composition একই reference syntax ব্যবহার করতে পারে।
private Learner learner;
Difference syntax-এ নয়।
Difference design meaning এবং lifecycle ownership-এ।
Relationship Summary
| Relationship | Meaning |
|---|---|
| Association | Objects collaborate বা connected |
| Aggregation | Whole references independently existing parts |
| Composition | Whole strongly owns or controls its parts |
| Inheritance | One type is a specialized form of another type |
Beginner level-এ সবচেয়ে important question:
Objectটি কি অন্য object-এর একটি type, নাকি objectটি অন্য object-কে ধারণ করে বা ব্যবহার করে?
is-a vs has-a
Inheritance-এর জন্য common test:
Learner is a User
Instructor is a User
Composition-এর জন্য:
Enrollment has a Learner
Course has Lessons
Wrong:
Enrollment is a Learner
Course is a Lesson
Relationship sentence যদি natural না হয়, inheritance সম্ভবত ভুল।
Composition Often Reduces Coupling
Inheritance parent class-এর implementation এবং lifecycle-এর সঙ্গে child class tightly connect করতে পারে।
Composition collaboration explicit করে।
Example:
public class Enrollment {
private final Learner learner;
private final Course course;
}
Enrollment learner বা course-এর subclass নয়।
এটি তাদের references ব্যবহার করে নিজের responsibility perform করে।
Composition:
- Responsibilities আলাদা রাখে
- Independent testing সহজ করে
- Objects replace করা সহজ করে
- Deep inheritance hierarchy avoid করে
Accessing Nested Objects
Enrollment getter expose করতে পারে:
public Learner getLearner() {
return learner;
}
public Course getCourse() {
return course;
}
Usage:
String learnerName =
enrollment
.getLearner()
.getName();
String courseTitle =
enrollment
.getCourse()
.getTitle();
This is method chaining।
Avoid Excessive Navigation
Code:
enrollment
.getLearner()
.getProfile()
.getAddress()
.getCountry()
.getCode();
এ ধরনের long navigation chain caller-কে internal object graph-এর ওপর tightly dependent করতে পারে।
Sometimes a focused query clearer:
enrollment.getLearnerCountryCode();
কিন্তু প্রতিটি nested property-এর wrapper method তৈরি করাও unnecessary।
Balance প্রয়োজন।
Ask:
- Caller-এর কি actual related object প্রয়োজন?
- নাকি specific business information প্রয়োজন?
- Object graph future-এ change হওয়ার সম্ভাবনা কত?
Object Collaboration
Enrollment তার Course object থেকে total lesson count নিতে পারে।
public boolean completeLessons(
int lessonCount
) {
if (!active) {
return false;
}
if (lessonCount <= 0) {
return false;
}
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> course.getTotalLessons()
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
Enrollment total lesson count duplicate করে না।
এটি Course-কে query করে।
Calculating Progress Through Collaboration
public double calculateProgress() {
return completedLessons
* 100.0
/ course.getTotalLessons();
}
The course owns:
totalLessons
The enrollment owns:
completedLessons
Progress calculation requires both।
Enrollment এই relationship-specific calculation-এর appropriate owner।
Complete Enrollment Class
public class Enrollment {
private final Learner learner;
private final Course course;
private int completedLessons;
private boolean active;
public Enrollment(
Learner learner,
Course course
) {
if (learner == null) {
throw new IllegalArgumentException(
"Learner is required."
);
}
if (course == null) {
throw new IllegalArgumentException(
"Course is required."
);
}
if (!course.isPublished()) {
throw new IllegalArgumentException(
"Cannot enroll in an unpublished course."
);
}
this.learner = learner;
this.course = course;
this.completedLessons = 0;
this.active = true;
}
public boolean completeLessons(
int lessonCount
) {
if (!active) {
return false;
}
if (lessonCount <= 0) {
return false;
}
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> course.getTotalLessons()
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
public boolean cancel() {
if (!active) {
return false;
}
if (isCompleted()) {
return false;
}
active = false;
return true;
}
public double calculateProgress() {
return completedLessons
* 100.0
/ course.getTotalLessons();
}
public int calculateRemainingLessons() {
return course.getTotalLessons()
- completedLessons;
}
public boolean isCompleted() {
return completedLessons
== course.getTotalLessons();
}
public Learner getLearner() {
return learner;
}
public Course getCourse() {
return course;
}
public int getCompletedLessons() {
return completedLessons;
}
public boolean isActive() {
return active;
}
}
Complete Usage Example
public class Main {
public static void main(String[] args) {
Learner jalisa =
new Learner(
1L,
"Jalisa",
"jalisa@example.com"
);
Course javaCourse =
new Course(
"JAVA",
"Java and OOP Foundation",
20
);
javaCourse.publish();
Enrollment enrollment =
new Enrollment(
jalisa,
javaCourse
);
enrollment.completeLessons(
8
);
System.out.println(
"Learner: "
+ enrollment
.getLearner()
.getName()
);
System.out.println(
"Course: "
+ enrollment
.getCourse()
.getTitle()
);
System.out.println(
"Progress: "
+ "%.2f%%".formatted(
enrollment
.calculateProgress()
)
);
System.out.println(
"Remaining lessons: "
+ enrollment
.calculateRemainingLessons()
);
}
}
Output:
Learner: Jalisa
Course: Java and OOP Foundation
Progress: 40.00%
Remaining lessons: 12
What Happens When a Related Object Changes?
Suppose Course title mutable:
course.changeTitle(
"Modern Java and OOP"
);
Since Enrollment same Course object refer করছে:
enrollment
.getCourse()
.getTitle();
updated title return করবে।
এই behavior useful হতে পারে।
কিন্তু সব data dynamically shared হওয়া উচিত কি না, তা domain decision।
Snapshot vs Live Reference
Two design choices:
Live Reference
Enrollment current Course object refer করে।
private final Course course;
Course title change হলে enrollment updated title দেখে।
Snapshot
Enrollment creation-এর সময় title copy করে।
private final String courseTitleAtEnrollment;
Course title পরে change হলেও enrollment historical title preserve করে।
কোনটি correct তা requirement-এর ওপর depend করে।
Examples:
Current course page → Live reference useful
Historical invoice → Snapshot required
Legal contract → Snapshot required
Audit record → Snapshot often required
Important:
Duplicate data সবসময় ভুল নয়। Intentional historical snapshot এবং accidental duplication আলাদা।
Relationship Ownership
Ask:
কোন object relationship create, modify, এবং remove করার responsibility নেবে?
Example:
Can any caller create Enrollment directly?
Should Course create Enrollment?
Should an EnrollmentService create it?
Simple domain-এ direct constructor acceptable।
Complex rules থাকলে creation service handle করতে পারে:
Course published?
Enrollment open?
Learner already enrolled?
Payment confirmed?
Capacity available?
সব rules Enrollment constructor নিজে check করতে পারবে না, কারণ external data প্রয়োজন হতে পারে।
Object Relationships and null
Required relationship null হতে দেওয়া উচিত নয়।
public Enrollment(
Learner learner,
Course course
) {
if (learner == null) {
throw new IllegalArgumentException(
"Learner is required."
);
}
if (course == null) {
throw new IllegalArgumentException(
"Course is required."
);
}
}
এতে পরে বারবার check করতে হয় না:
if (course != null) {
}
Required collaborator constructor-এ enforce করা stronger design।
Circular Relationships
Potential design:
class Learner {
private List<Enrollment> enrollments;
}
class Enrollment {
private Learner learner;
}
এখন:
Learner → Enrollment
Enrollment → Learner
Circular reference technically valid।
কিন্তু risks:
toString()infinite recursion- JSON serialization loops
- Relationship synchronization complexity
- Memory graph বোঝা কঠিন
- Add/remove logic দুই দিকে maintain করতে হয়
Bidirectional relationship শুধু প্রয়োজন হলে ব্যবহার করুন।
Simple design-এ এক দিকের navigation যথেষ্ট হতে পারে।
Unidirectional vs Bidirectional Relationship
Unidirectional
Enrollment → Learner
Enrollment learner জানে।
Learner নিজের enrollments জানে না।
Bidirectional
Enrollment → Learner
Learner → Enrollments
দুই দিক থেকেই navigate করা যায়।
Bidirectional design convenience দেয়, কিন্তু consistency maintain করতে হয়।
Example:
Enrollment learner-এর list-এ আছে
Enrollment নিজেও same learner point করছে
এক দিক update হয়ে অন্য দিক না হলে graph inconsistent।
Encapsulating Relationship Changes
If Course owns lessons:
public boolean addLesson(
Lesson lesson
) {
if (lesson == null) {
return false;
}
return lessons.add(
lesson
);
}
Avoid exposing mutable internal list:
public List<Lesson> getLessons() {
return lessons;
}
Caller directly add/remove করতে পারে।
Safer:
public List<Lesson> getLessons() {
return List.copyOf(
lessons
);
}
Collections বিস্তারিত পরে শেখানো হবে।
Principle:
Relationship mutationও object invariants-এর অংশ।
Composition Does Not Mean One Giant Object
Wrong direction:
public class Course {
private Learner learner;
private Enrollment enrollment;
private Payment payment;
private Certificate certificate;
private Notification notification;
}
সব related concept একটি root object-এর মধ্যে ঢুকিয়ে দেওয়া composition নয়।
Good composition requires:
- Clear ownership
- Meaningful lifecycle
- Focused responsibilities
- Necessary collaboration
Avoid Feature Envy
Suppose application code repeatedly does:
int remaining =
enrollment
.getCourse()
.getTotalLessons()
- enrollment
.getCompletedLessons();
এই calculation relationship-specific।
Better:
enrollment.calculateRemainingLessons();
যখন caller অন্য object-এর internal data নিয়ে repeatedly business logic perform করে, behaviorটি wrong location-এ থাকতে পারে।
Avoid Passing Raw IDs Everywhere
Weak domain interaction:
createEnrollment(
learnerId,
courseCode,
totalLessons,
learnerName,
courseTitle
);
Object-based interaction:
new Enrollment(
learner,
course
);
Objects already validated state এবং behavior carry করে।
তবে application boundaries-এ IDs natural:
HTTP request
Database lookup
Message event
Boundary IDs resolve করে domain objects তৈরি বা load করতে পারে।
Engineering Note: Entities Across Service Boundaries
একটি distributed system-এ Learner এবং Course different services-এর ownership-এ থাকতে পারে।
এক service-এর Java object reference অন্য service-এর live object নয়।
তখন enrollment service হয়তো store করবে:
learnerId
courseId
courseTitleSnapshot
totalLessonsSnapshot
এটি accidental duplication নাও হতে পারে।
It may be deliberate because:
- Services have separate databases
- Historical state preserve করতে হয়
- Remote service unavailable হতে পারে
- Independent deployment required
In-process OOP composition এবং distributed data ownership একই problem নয়।
Beginner class design থেকে production architecture-এ যাওয়ার সময় boundary বুঝতে হবে।
Composition vs Inheritance
Suppose:
Enrollment uses Course
Wrong inheritance:
public class Enrollment
extends Course {
}
Enrollment কোনো Course নয়।
Correct composition:
public class Enrollment {
private final Course course;
}
Use inheritance only when:
- Child truly parent type
- Substitution meaningful
- Shared contract stable
- Relationship
is-a
Use composition when:
- Object uses another object
- Object contains another object
- Object delegates behavior
- Relationship
has-a
Common Mistakes
Duplicating Related Object Data
private String learnerName;
private String learnerEmail;
যখন actual Learner object already exists।
Using Inheritance for a has-a Relationship
Enrollment extends Learner
Invalid domain meaning।
Exposing Mutable Child Collections
Caller relationship rules bypass করতে পারে।
Allowing Required Relationships to Be null
Later code null checks এবং runtime failures বাড়ায়।
Making Every Relationship Bidirectional
Object graph এবং consistency unnecessarily complex হয়।
Copying Live Data Without Deciding Snapshot Semantics
Course title duplicate করলে decide করতে হবে:
Live current title?
Historical title at enrollment?
Putting All Related Objects into One Class
Composition clear ownership require করে; random references নয়।
Letting Callers Perform Relationship Logic
course.getTotalLessons()
- enrollment.getCompletedLessons();
Repeated domain calculation appropriate object-এর method হওয়া উচিত।
Practice Exercises
Exercise 1: Refactor Duplicate State
Refactor:
public class Enrollment {
private long learnerId;
private String learnerName;
private String learnerEmail;
private String courseCode;
private String courseTitle;
}
Use:
Learner
Course
objects।
Exercise 2: Identify Relationships
Classify:
EnrollmentreferencesLearnerCourseownsLessonobjectsInstructorextendsUserTeamreferences independently existing engineers
Choose:
Association
Aggregation
Composition
Inheritance
Exercise 3: Design a Lesson
Create a Lesson class with:
lessonId
title
durationInMinutes
Then decide whether Course should reference lessons।
Explain ownership।
Exercise 4: Snapshot Decision
A learner enrolls when course title is:
Java Foundation
Later title changes to:
Java and OOP Foundation
Decide which title should appear in:
- Current learner dashboard
- Historical invoice
- Completion certificate
Explain live reference vs snapshot choice।
Exercise 5: Avoid Circular Navigation
Decide whether both are required:
Learner → Enrollments
Enrollment → Learner
Give one case where bidirectional relationship is useful and one where unidirectional is enough।
Exercise 6: Move Behavior
Refactor:
int remaining =
enrollment
.getCourse()
.getTotalLessons()
- enrollment
.getCompletedLessons();
Move behavior to the appropriate object।
Exercise 7: Composition or Inheritance?
Choose composition or inheritance:
- Car and Engine
- Learner and User
- Course and Lesson
- Enrollment and Course
- EmailNotification and Notification
Explain each briefly।
Predict the Result
Question 1
Course course =
new Course(
"JAVA",
"Java Foundation",
20
);
course.publish();
Enrollment first =
new Enrollment(
nur,
course
);
Enrollment second =
new Enrollment(
jalisa,
course
);
Do first and second reference the same Course object?
Question 2
If the shared Course title changes, what title will both enrollments observe through getCourse()?
Assume no snapshot field exists।
Question 3
If Enrollment constructor rejects null course, can a successfully constructed enrollment have a null course through normal public API?
Assume the field is private final and no setter exists।
Question 4
Is this relationship inheritance or composition?
class Order {
private List<OrderItem> items;
}
Predict the Result Answers
Answer 1
হ্যাঁ।
Both enrollments same course reference received করেছে।
Answer 2
Updated course title।
They hold a live reference to the same object।
Answer 3
না।
Constructor establishes the relationship এবং external caller field reassign করতে পারে না।
Answer 4
Composition।
Order contains or owns its OrderItem objects।
Knowledge Check
Question 1
একটি object অন্য object-এর reference field হিসেবে রাখলে কী relationship তৈরি হয়?
Question 2
has-a relationship কী?
Question 3
Association এবং composition-এর difference কী?
Question 4
Duplicate state problematic কেন?
Question 5
Enrollment কেন learner name copy না করে Learner object রাখতে পারে?
Question 6
Progress কেন Course বা Learner-এর পরিবর্তে Enrollment-এর behavior?
Question 7
Required object relationships constructor-এ নেওয়া useful কেন?
Question 8
Live reference এবং snapshot-এর difference কী?
Question 9
Bidirectional relationship-এর risk কী?
Question 10
Composition inheritance-এর চেয়ে কখন better?
Question 11
Intentional historical snapshot কি সবসময় bad duplication?
Question 12
Distributed services-এর মধ্যে Java object reference share করা যায় কি?
Knowledge Check Answers
Answer 1
Association বা composition-এর মতো object relationship।
Answer 2
একটি object অন্য object-কে ধারণ করে, reference করে, বা ব্যবহার করে।
Answer 3
Association general collaboration। Composition stronger ownership এবং lifecycle relationship বোঝায়।
Answer 4
Values inconsistent হতে পারে এবং update rules multiple জায়গায় maintain করতে হয়।
Answer 5
Learner information-এর single owner থাকে এবং repeated validation বা stale copy avoid হয়।
Answer 6
Progress একটি specific learner এবং course relationship-এর state।
Answer 7
Object শুরু থেকেই complete থাকে এবং repeated null checks কমে।
Answer 8
Live reference current related object state দেখে। Snapshot নির্দিষ্ট সময়ের copied state preserve করে।
Answer 9
Both sides synchronize করতে হয়; serialization loops এবং object graph complexity তৈরি হতে পারে।
Answer 10
যখন relationship has-a, object collaboration প্রয়োজন, অথবা inheritance substitution natural নয়।
Answer 11
না। Invoice, audit, certificate বা legal record-এর জন্য snapshot intentional এবং necessary হতে পারে।
Answer 12
না। Services IDs, messages, API data, বা snapshots exchange করে; live in-memory object references নয়।
Lesson Summary
এই lesson-এ আমরা শিখেছি:
- Objects অন্য objects-এর references রাখতে পারে
has-arelationship association এবং composition-এর foundationLearner,Course, এবংEnrollmentআলাদা responsibilities own করে- Enrollment learner এবং course relationship-specific state track করে
- Related object data blindly duplicate করলে consistency সমস্যা হয়
- Constructor required object relationships enforce করতে পারে
- Object collaboration nested state এবং behavior reuse করতে দেয়
- Association general connection represent করে
- Composition stronger ownership এবং lifecycle relationship represent করে
- Aggregation independently existing parts-এর weaker ownership relationship
- Relationship meaning syntax-এর চেয়ে domain design-এর ওপর depend করে
- Live reference current object state observe করে
- Snapshot historical state preserve করে
- Intentional snapshot accidental duplication নয়
- Bidirectional relationships convenience-এর সঙ্গে complexity আনে
- Required relationships null না হতে দেওয়া safer
- Relationship mutation encapsulate করা উচিত
- Composition one giant object তৈরি করার নাম নয়
- Repeated external relationship logic appropriate object-এর method-এ move করা যায়
has-arelationship-এর জন্য inheritance ব্যবহার করা উচিত নয়- Composition often lower coupling এবং clearer responsibilities দেয়
- Distributed service boundaries in-process object composition-এর চেয়ে different data design require করে
Next Lesson
পরবর্তী lesson:
Designing Immutable Objects
আমরা শিখব:
- Mutable এবং immutable object
finalfields- Constructor-only initialization
- Setters বাদ দেওয়া
- Immutable value objects
- Defensive copying
- Benefits for concurrency and reasoning
- When immutability is appropriate
- When controlled mutability is still necessary