Object-Oriented Programming Foundations
Encapsulation, Access Control, and Object Invariants
You are viewing a free preview lesson.
Lesson Overview
আগের lesson-এ constructor ব্যবহার করে একটি object-কে valid state-এ তৈরি করেছি।
Enrollment enrollment =
new Enrollment(
"Nur",
"Java and OOP Foundation",
20
);
Constructor নিশ্চিত করেছে:
Learner name blank নয়
Course title blank নয়
Total lessons zero-এর বেশি
Completed lessons শুরু হয়েছে zero থেকে
কিন্তু fields direct accessible থাকলে caller constructor-এর validation bypass করতে পারে।
enrollment.completedLessons = -10;
enrollment.totalLessons = 0;
Object valid state-এ তৈরি হলেও পরে invalid হয়ে গেল।
Encapsulation এই সমস্যা সমাধান করে।
এর উদ্দেশ্য:
- Internal state hide করা
- State পরিবর্তনের পথ control করা
- Business rules enforce করা
- Object-এর public API meaningful রাখা
- Implementation future-এ পরিবর্তন করার freedom রাখা
এই lesson-এ আমরা শিখব:
- Encapsulation কী
privatefields কেন প্রয়োজন- Java access modifiers
- Public object API
- Getters এবং setters
- কেন every field-এর setter থাকা উচিত নয়
- Object invariants
- Behavior-focused methods
- Constructor এবং methods কীভাবে একসঙ্গে object validity রক্ষা করে
Learning Objectives
এই lesson শেষ করার পর আপনি পারবেন:
- Encapsulation-এর purpose ব্যাখ্যা করতে
- Fields
privateকরতে public,private, package-private এবংprotected-এর basic difference বুঝতে- Controlled getters এবং methods expose করতে
- Unnecessary setters avoid করতে
- Object invariant define করতে
- Invalid state transitions prevent করতে
- Constructor validation এবং method validation-এর relationship বুঝতে
- Behavior-focused object API design করতে
The Problem with Direct Field Access
Current class:
public class Enrollment {
String learnerName;
String courseTitle;
int completedLessons;
int totalLessons;
}
Caller যেকোনো field direct change করতে পারে।
enrollment.completedLessons = 500;
enrollment.totalLessons = 20;
এখন progress:
2500%
আরও invalid states:
enrollment.learnerName = null;
enrollment.courseTitle = "";
enrollment.completedLessons = -5;
enrollment.totalLessons = -1;
Class-এর methods যত ভালো validationই করুক, direct field access caller-কে সব rules bypass করতে দেয়।
What Is Encapsulation?
Encapsulation হলো:
- Object-এর internal state এবং related behavior একসঙ্গে রাখা
- সেই state কীভাবে read এবং change করা যাবে তা control করা
Fields সাধারণত private রাখা হয়।
public class Enrollment {
private String learnerName;
private String courseTitle;
private int completedLessons;
private int totalLessons;
}
এখন অন্য class direct field access করতে পারবে না।
Wrong:
enrollment.completedLessons = 10;
Compiler error হবে।
Caller-কে object-এর public methods ব্যবহার করতে হবে।
enrollment.completeLessons(10);
এখানে object নিজেই state transition validate করতে পারে।
private Fields
private member শুধু একই class-এর ভেতরে accessible।
public class Enrollment {
private int completedLessons;
public boolean completeLesson() {
completedLessons++;
return true;
}
}
Enrollment class-এর methods field access করতে পারে।
External caller direct access করতে পারে না।
Encapsulation Is More Than private
শুধু field private করলেই good encapsulation complete হয় না।
Example:
private int completedLessons;
public void setCompletedLessons(
int completedLessons
) {
this.completedLessons =
completedLessons;
}
Caller এখনো লিখতে পারে:
enrollment.setCompletedLessons(
-500
);
Field technically private, কিন্তু state effectively uncontrolled।
Better question:
Caller-এর কি completed lesson count arbitrary value-তে set করার প্রয়োজন আছে?
Usually no।
Meaningful operation:
enrollment.completeLesson();
অথবা:
enrollment.completeLessons(3);
এগুলো domain behavior express করে এবং rules enforce করতে পারে।
Behavior-Focused API
Weak API:
enrollment.setCompletedLessons(5);
enrollment.setActive(false);
Caller low-level state manipulate করছে।
Stronger API:
enrollment.completeLessons(5);
enrollment.cancel();
এই methods intent প্রকাশ করে।
Object decide করতে পারে:
- Operation valid কি না
- কোন fields change হবে
- কোন state transition allowed
- Additional rules apply হবে কি না
Object Invariants
Object invariant হলো এমন rule, যা valid object-এর lifetime জুড়ে true থাকা উচিত।
Enrollment invariants:
Learner name blank নয়
Course title blank নয়
Total lessons zero-এর বেশি
Completed lessons negative নয়
Completed lessons total lessons-এর বেশি নয়
Cancelled enrollment-এর progress update করা যাবে না
Constructor initial invariants establish করে।
Public methods future changes-এর সময় invariants preserve করে।
Constructor and Encapsulation Work Together
Constructor:
Object-কে valid state-এ তৈরি করে
Encapsulation:
Object তৈরির পরে invalid state তৈরি হওয়া prevent করে
একটি ছাড়া অন্যটি incomplete protection দেয়।
A Properly Encapsulated Enrollment
public class Enrollment {
private String learnerName;
private String courseTitle;
private int completedLessons;
private int totalLessons;
private boolean active;
public Enrollment(
String learnerName,
String courseTitle,
int totalLessons
) {
if (
learnerName == null
|| learnerName.isBlank()
) {
throw new IllegalArgumentException(
"Learner name is required."
);
}
if (
courseTitle == null
|| courseTitle.isBlank()
) {
throw new IllegalArgumentException(
"Course title is required."
);
}
if (totalLessons <= 0) {
throw new IllegalArgumentException(
"Total lessons must be greater than zero."
);
}
this.learnerName =
learnerName.strip();
this.courseTitle =
courseTitle.strip();
this.completedLessons = 0;
this.totalLessons =
totalLessons;
this.active = true;
}
}
External code এখন fields direct modify করতে পারবে না।
Object-এর public methods define করবে কোন operations allowed।
Public Behavior
public boolean completeLessons(
int lessonCount
) {
if (!active) {
return false;
}
if (lessonCount <= 0) {
return false;
}
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> totalLessons
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
Method invariants protect করছে:
Inactive enrollment change হবে না
Negative বা zero lesson count accepted নয়
Completed count total exceed করবে না
State Transition Methods
Enrollment cancel করার জন্য:
public boolean cancel() {
if (!active) {
return false;
}
if (isCompleted()) {
return false;
}
active = false;
return true;
}
Possible contract:
Already inactive enrollment cancel করা যাবে না
Completed enrollment cancel করা যাবে না
Successful cancellation active state false করবে
Caller শুধু লিখবে:
enrollment.cancel();
Internal fields কীভাবে change হচ্ছে, তা caller-এর জানা দরকার নেই।
Query Methods
Query methods object state সম্পর্কে information return করে।
public double calculateProgress() {
return completedLessons
* 100.0
/ totalLessons;
}
public boolean isCompleted() {
return completedLessons
== totalLessons;
}
public boolean isActive() {
return active;
}
Queries ideally state change করবে না।
Getters
Getter একটি field-এর value caller-এর কাছে expose করে।
public String getLearnerName() {
return learnerName;
}
public int getCompletedLessons() {
return completedLessons;
}
Usage:
System.out.println(
enrollment.getLearnerName()
);
Boolean Getter Naming
Boolean query সাধারণত is বা has দিয়ে শুরু হয়।
public boolean isActive() {
return active;
}
public boolean isCompleted() {
return completedLessons
== totalLessons;
}
getActive() technically possible হলেও isActive() বেশি natural।
Not Every Field Needs a Getter
Private field মানেই automatic getter তৈরি করতে হবে—এমন নয়।
Ask:
Caller-এর কি raw field value জানা প্রয়োজন?
Example:
private boolean internalReviewRequired;
এটি object implementation detail হতে পারে।
Caller-এর প্রয়োজন হতে পারে শুধু:
public boolean canPublish() {
return !internalReviewRequired
&& totalLessons > 0;
}
Raw internal flag expose না করেও useful business answer দেওয়া যায়।
Setters
Traditional setter:
public void setCourseTitle(
String courseTitle
) {
this.courseTitle =
courseTitle;
}
এটি validation ছাড়া weak।
Validated setter:
public boolean setCourseTitle(
String courseTitle
) {
if (
courseTitle == null
|| courseTitle.isBlank()
) {
return false;
}
this.courseTitle =
courseTitle.strip();
return true;
}
Technically better, কিন্তু naming আরও meaningful হতে পারে।
public boolean changeCourseTitle(
String newTitle
) {
if (
newTitle == null
|| newTitle.isBlank()
) {
return false;
}
courseTitle =
newTitle.strip();
return true;
}
changeCourseTitle() একটি domain operation-এর মতো পড়ে।
Why Blind Setters Are Dangerous
Consider:
public void setActive(
boolean active
) {
this.active = active;
}
Caller লিখতে পারে:
enrollment.setActive(false);
enrollment.setActive(true);
কিন্তু enrollment reactivation-এর business rules কী?
- Cancelled enrollment reactivate করা যাবে?
- Payment required?
- Course enrollment open?
- Admin permission required?
Generic setter এসব প্রশ্ন bypass করে।
Better methods:
cancel();
reactivate();
প্রতিটি method নিজের rules enforce করবে।
Getters and Setters Are Not Encapsulation by Themselves
এই class:
public class Enrollment {
private int completedLessons;
public int getCompletedLessons() {
return completedLessons;
}
public void setCompletedLessons(
int completedLessons
) {
this.completedLessons =
completedLessons;
}
}
ক্ষেত্রটিকে syntax-level private করেছে, কিন্তু caller এখনও arbitrary state assign করতে পারে।
Strong encapsulation asks:
- Which state should be visible?
- Which state should be mutable?
- Through which operations?
- Under which rules?
Java Access Modifiers
Java-তে commonly used access levels:
publicprivate- package-private
protected
public
সব accessible context থেকে member use করা যায়, যদি class নিজেও accessible হয়।
public boolean completeLesson() {
}
Public methods object-এর external API-এর অংশ।
Public API carefully design করা উচিত, কারণ callers এর ওপর depend করে।
private
শুধু একই class-এর ভেতরে accessible।
private int completedLessons;
Internal implementation details-এর জন্য commonly used।
Package-Private
কোনো modifier না দিলে member package-private।
int completedLessons;
Same package-এর classes access করতে পারে।
Other packages পারে না।
এটি accidental omission হিসেবে ব্যবহার করা উচিত নয়।
Package-level collaboration deliberately প্রয়োজন হলে ব্যবহার করুন।
protected
protected member:
- Same package থেকে accessible
- Subclasses থেকে accessible
protected int completedLessons;
Inheritance-related code-এ ব্যবহৃত হয়।
Beginner domain classes-এ fields protected করা সাধারণত প্রয়োজন হয় না।
Inheritance module-এ এটি বিস্তারিত শেখানো হবে।
Access Modifier Summary
| Modifier | Same Class | Same Package | Subclass | Other Packages |
|---|---|---|---|---|
private | Yes | No | No | No |
| Package-private | Yes | Yes | Same package rules | No |
protected | Yes | Yes | Yes, with rules | No direct general access |
public | Yes | Yes | Yes | Yes |
এই table conceptual overview।
protected access-এর exact cross-package rules inheritance শেখার সময় বিস্তারিত বোঝা হবে।
Minimize Public Surface Area
Class-এর যত বেশি public methods থাকবে, callers-এর সঙ্গে coupling তত বাড়তে পারে।
Public API-তে শুধু meaningful operations রাখা ভালো।
Weak API:
setLearnerName()
setCourseTitle()
setCompletedLessons()
setTotalLessons()
setActive()
setCancelled()
setProgress()
Focused API:
completeLessons()
cancel()
changeCourseTitle()
calculateProgress()
isCompleted()
isActive()
Small public API:
- Understand করা সহজ
- Test করা সহজ
- Misuse করা কঠিন
- Future-এ change করা সহজ
Derived State Should Usually Be Queried
Progress percentage fields থেকে calculate করা যায়।
private int completedLessons;
private int totalLessons;
Avoid storing:
private double progressPercentage;
কারণ source fields change হলে value stale হতে পারে।
Query:
public double calculateProgress() {
return completedLessons
* 100.0
/ totalLessons;
}
এতে result always current state থেকে আসে।
Avoid Exposing Mutable Internal Objects
Primitive এবং String getters relatively safe, কারণ caller returned value ব্যবহার করে internal object mutate করতে পারে না।
কিন্তু mutable object বা collection return করলে সমস্যা হতে পারে।
Conceptual example:
private List<String> completedLessonIds;
public List<String> getCompletedLessonIds() {
return completedLessonIds;
}
Caller লিখতে পারে:
enrollment
.getCompletedLessonIds()
.clear();
এতে internal state bypass হয়ে change হলো।
Safer options:
return List.copyOf(
completedLessonIds
);
Collections পরে শেখানো হবে।
এখানে principle:
Getter যেন caller-কে internal mutable state uncontrolledভাবে change করার সুযোগ না দেয়।
Validation Belongs Near the Rule
ধরা যাক:
Completed lessons cannot exceed total lessons.
এটি enrollment invariant।
এই rule Enrollment class-এর কাছেই থাকা উচিত।
public boolean completeLessons(
int lessonCount
) {
// Validate invariant
}
কিন্তু একটি rule যদি external information require করে:
Learner may enroll only if payment was confirmed by payment provider.
তাহলে শুধু Enrollment object যথেষ্ট নাও হতে পারে।
Application service বা domain service external collaboration handle করতে পারে।
Engineering Note: Not All Validation Belongs in One Place
Validation broadly তিন ধরনের হতে পারে।
Input Format Validation
Email format valid?
Request field present?
Number parse করা গেছে?
Usually boundary layer handle করতে পারে।
Object Invariant Validation
Total lessons greater than zero
Completed count cannot exceed total
Price cannot be negative
Domain object-এর কাছে থাকা উচিত।
External Rule Validation
Payment provider confirmed?
Database-এ email unique?
Course enrollment currently open?
External dependency প্রয়োজন হতে পারে।
Encapsulation মানে সব application logic একটি class-এর মধ্যে ঢুকিয়ে দেওয়া নয়।
A Complete Encapsulated Enrollment
Enrollment.java
public class Enrollment {
private final String learnerName;
private final String courseTitle;
private final int totalLessons;
private int completedLessons;
private boolean active;
public Enrollment(
String learnerName,
String courseTitle,
int totalLessons
) {
if (
learnerName == null
|| learnerName.isBlank()
) {
throw new IllegalArgumentException(
"Learner name is required."
);
}
if (
courseTitle == null
|| courseTitle.isBlank()
) {
throw new IllegalArgumentException(
"Course title is required."
);
}
if (totalLessons <= 0) {
throw new IllegalArgumentException(
"Total lessons must be greater than zero."
);
}
this.learnerName =
learnerName.strip();
this.courseTitle =
courseTitle.strip();
this.totalLessons =
totalLessons;
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
> totalLessons
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
public boolean cancel() {
if (!active) {
return false;
}
if (isCompleted()) {
return false;
}
active = false;
return true;
}
public String getLearnerName() {
return learnerName;
}
public String getCourseTitle() {
return courseTitle;
}
public int getCompletedLessons() {
return completedLessons;
}
public int getTotalLessons() {
return totalLessons;
}
public int calculateRemainingLessons() {
return totalLessons
- completedLessons;
}
public double calculateProgress() {
return completedLessons
* 100.0
/ totalLessons;
}
public boolean isCompleted() {
return completedLessons
== totalLessons;
}
public boolean isActive() {
return active;
}
}
Why Some Fields Are final
private final String learnerName;
private final String courseTitle;
private final int totalLessons;
final means field reference বা primitive value constructor assignment-এর পরে reassign করা যাবে না।
এই design ধরে নিচ্ছে:
- Enrollment অন্য learner-এর কাছে transfer হবে না
- Enrollment অন্য course-এ move হবে না
- Course lesson count snapshot enrollment creation-এর সময় fixed
এটি সব system-এর জন্য correct নাও হতে পারে।
Design decision domain rules-এর ওপর নির্ভর করে।
Immutability lesson-এ final বিস্তারিত শেখানো হবে।
Using the Encapsulated Object
Main.java
public class Main {
public static void main(String[] args) {
Enrollment nurEnrollment =
new Enrollment(
"Nur",
"Java and OOP Foundation",
20
);
boolean progressUpdated =
nurEnrollment
.completeLessons(8);
if (!progressUpdated) {
System.out.println(
"Progress update failed."
);
return;
}
System.out.println(
"Learner: "
+ nurEnrollment
.getLearnerName()
);
System.out.println(
"Course: "
+ nurEnrollment
.getCourseTitle()
);
System.out.println(
"Progress: "
+ "%.2f%%".formatted(
nurEnrollment
.calculateProgress()
)
);
System.out.println(
"Remaining lessons: "
+ nurEnrollment
.calculateRemainingLessons()
);
System.out.println(
"Active: "
+ nurEnrollment.isActive()
);
}
}
Output:
Learner: Nur
Course: Java and OOP Foundation
Progress: 40.00%
Remaining lessons: 12
Active: true
External code cannot do:
nurEnrollment.completedLessons = -100;
Compiler prevents direct access।
Design Trade-Off: Returning boolean
Current commands return boolean:
boolean completeLessons(
int lessonCount
)
This keeps the example simple।
Limitation:
false
does not explain why operation failed।
Possible reasons:
- Enrollment inactive
- Count not positive
- Total exceeded
Production design alternatives:
- Throw domain-specific exception
- Return an enum
- Return a result object
- Use different application-layer error handling
Example concept:
ProgressUpdateResult result =
enrollment.completeLessons(3);
Result could distinguish:
UPDATED
INACTIVE_ENROLLMENT
INVALID_LESSON_COUNT
TOTAL_EXCEEDED
For beginner code, boolean is enough।
The important point হলো failure contract intentional হওয়া উচিত।
Common Mistakes
Making Fields Public
public int completedLessons;
Caller invariants bypass করতে পারে।
Creating Setters for Every Field
setCompletedLessons()
setTotalLessons()
setActive()
এগুলো object state uncontrolled করে দিতে পারে।
Performing No Validation in Setters
public void setTotalLessons(
int totalLessons
) {
this.totalLessons =
totalLessons;
}
Negative এবং zero values accepted হয়।
Exposing Internal Implementation
Caller-এর শুধু canEnroll() প্রয়োজন, কিন্তু class অনেক internal flags expose করছে।
Public API domain questions answer করা উচিত।
Returning Mutable Internal State
Getter দিয়ে internal collection return করলে caller state bypass করে modify করতে পারে।
Putting External Work Inside the Domain Object
public void cancel() {
active = false;
database.save(this);
emailService.sendEmail();
}
এটি state transition, persistence এবং communication mix করে।
Domain object state rule enforce করতে পারে।
Application layer persistence এবং notifications coordinate করতে পারে।
Believing private Makes an Object Immutable
private শুধু access restrict করে।
Class-এর own methods state change করতে পারে।
private int completedLessons;
public void completeLesson() {
completedLessons++;
}
Object এখনও mutable।
Practice Exercises
Exercise 1: Encapsulate Course
Fields:
title
priceInPaisa
totalLessons
published
Requirements:
- Fields
private - Constructor required values validate করবে
- Negative price reject করবে
- Blank title reject করবে
publish()method থাকবে- Direct
setPublished()থাকবে না
Exercise 2: Design Meaningful Methods
Replace these setters:
setCompletedLessons
setActive
setPublished
setPrice
with meaningful operations for:
Enrollment
Course
Exercise 3: Define Invariants
একটি Course object-এর জন্য অন্তত চারটি invariants লিখুন।
Example fields:
title
priceInPaisa
totalLessons
published
Exercise 4: Getter or Query?
Decide which API is clearer:
getCompletedLessons()
or:
isCompleted()
Explain why both may be useful but answer different questions।
Exercise 5: Access Modifiers
Choose an appropriate modifier:
- Enrollment internal progress count
- Public
completeLesson()operation - Internal validation helper used only by the same class
- A member intentionally shared only within the same package
Exercise 6: Identify Weak Encapsulation
public class Course {
private long priceInPaisa;
public void setPriceInPaisa(
long priceInPaisa
) {
this.priceInPaisa =
priceInPaisa;
}
}
Explain why this is not enough।
Improve the method।
Exercise 7: Separate Responsibilities
Review:
public boolean publish() {
published = true;
database.save(this);
emailService.notifyLearners();
return true;
}
Identify which responsibilities should remain in the object and which should move elsewhere।
Predict the Result
Question 1
public class Enrollment {
private int completedLessons;
}
Can Main do this?
enrollment.completedLessons = 5;
Question 2
public boolean completeLessons(
int count
) {
if (count <= 0) {
return false;
}
completedLessons +=
count;
return true;
}
What invariant is still unprotected?
Question 3
public boolean isCompleted() {
return completedLessons
== totalLessons;
}
Does this method need a setter?
Question 4
Can a class with only private fields still be mutable?
Predict the Result Answers
Answer 1
না।
completedLessons শুধু Enrollment class-এর ভেতরে accessible।
Answer 2
Completed lesson count total lessons exceed করতে পারে।
Updated state commit করার আগে total validate করতে হবে।
Answer 3
না।
isCompleted() existing state থেকে derived answer return করে।
Answer 4
হ্যাঁ।
Public বা private methods fields change করলে object mutable।
Knowledge Check
Question 1
Encapsulation কী?
Question 2
Fields private রাখার benefit কী?
Question 3
private field কি same class-এর method access করতে পারে?
Question 4
Every private field-এর getter এবং setter প্রয়োজন কি?
Question 5
Blind setter কেন risky?
Question 6
Object invariant কী?
Question 7
Constructor এবং public methods invariants কীভাবে protect করে?
Question 8
public methods কী represent করে?
Question 9
Package-private access কী?
Question 10
protected সাধারণত কোন context-এ useful?
Question 11
Derived progress আলাদা field হিসেবে store না করাই ভালো কেন?
Question 12
Mutable internal collection direct return করা risky কেন?
Question 13
Validation-এর সব ধরনের rule কি domain object-এর মধ্যে থাকা উচিত?
Question 14
private fields কি object-কে automatically immutable করে?
Knowledge Check Answers
Answer 1
Object-এর internal state hide করা এবং সেই state read ও change করার controlled API expose করা।
Answer 2
Caller direct mutation করে invariants ভাঙতে পারে না।
Answer 3
হ্যাঁ।
Answer 4
না। শুধু caller-এর প্রয়োজনীয় information এবং operations expose করা উচিত।
Answer 5
Caller arbitrary value assign করে invalid state তৈরি করতে পারে।
Answer 6
Object-এর valid lifetime জুড়ে true থাকা উচিত এমন rule।
Answer 7
Constructor valid initial state তৈরি করে। Public methods valid state transitions enforce করে।
Answer 8
Object-এর external contract বা API।
Answer 9
কোনো modifier না দিলে member same package-এর classes থেকে accessible হয়।
Answer 10
Inheritance এবং subclass access-এর ক্ষেত্রে।
Answer 11
Source fields change হলে stored derived value stale হতে পারে।
Answer 12
Caller object-এর controlled methods bypass করে internal state modify করতে পারে।
Answer 13
না। Input format, domain invariants এবং external dependency rules আলাদা layers-এ থাকতে পারে।
Answer 14
না। Class methods state change করলে object mutable থাকে।
Lesson Summary
এই lesson-এ আমরা শিখেছি:
- Constructor valid object তৈরি করে
- Encapsulation সেই validity object lifetime জুড়ে protect করে
- Direct field access caller-কে rules bypass করতে দেয়
privatefields internal state hide করে- Public methods object-এর external API তৈরি করে
- Encapsulation শুধু private fields এবং getters/setters নয়
- Blind setters invalid state allow করতে পারে
- Meaningful methods domain intent এবং rules প্রকাশ করে
- Object invariants valid state define করে
- Constructor initial invariants establish করে
- Commands valid state transitions enforce করে
- Queries state read করে এবং ideally mutation করে না
- Every field-এর getter প্রয়োজন নেই
- Every field-এর setter থাকা উচিত নয়
- Public API যত ছোট এবং focused হয়, misuse তত কমে
public,private, package-private এবংprotecteddifferent visibility দেয়- Derived state সাধারণত calculate করা safer
- Mutable internal objects direct expose করা উচিত নয়
- Core domain validation object-এর কাছে রাখা যায়
- External rules application বা service layer require করতে পারে
privateobject-কে automatically immutable করে না- Strong encapsulation object-কে নিজের rules protect করার ক্ষমতা দেয়
Next Lesson
পরবর্তী lesson:
Static and Instance Members
আমরা শিখব:
- Instance fields এবং methods
- Static fields এবং methods
- Per-object state এবং class-level state
- Shared counters
static finalconstants- Static context-এর limitations
- Why utility methods may be static
- Why domain state usually should not be global