Object-Oriented Programming Foundations
Module Review and Assessment
You are viewing a free preview lesson.
Module Overview
এই module-এ আমরা শুধু Java syntax শিখিনি।
আমরা শিখেছি কীভাবে real-world concepts-কে classes, objects, state, behavior, এবং relationships দিয়ে model করতে হয়।
Module-এর শুরুতে আমাদের object design ছিল এমন:
Enrollment enrollment =
new Enrollment();
enrollment.learnerName = "Nur";
enrollment.courseTitle =
"Java and OOP Foundation";
enrollment.completedLessons = 5;
enrollment.totalLessons = 20;
এটি compile করতে পারে, কিন্তু design হিসেবে দুর্বল।
কারণ caller:
- Required field assign করতে ভুলে যেতে পারে
- Invalid value দিতে পারে
- Business rules bypass করতে পারে
- Related data duplicate করতে পারে
- Object-কে inconsistent state-এ নিতে পারে
Module শেষে আমরা এমন design তৈরি করেছি:
Course course =
Course.freeCourse(
new CourseCode(
"java-foundation"
),
"Java and OOP Foundation",
20
);
course.publish();
Learner learner =
new Learner(
1L,
"Nur",
"nur@example.com"
);
Enrollment enrollment =
Enrollment.enroll(
learner,
course
);
enrollment.completeLessons(
5
);
এখানে:
- Objects valid state-এ তৈরি হয়
- Fields encapsulated
- Domain operations meaningful
- Invalid transitions rejected
- Relationships composition দিয়ে modeled
- Identity এবং equality intentional
- Package organization clear
- Immutable values safely shared
এই lesson পুরো module revise করবে এবং আপনার design judgment assess করবে।
Learning Objectives
এই lesson শেষ করার পর আপনি পারবেন:
- Module 2-এর core concepts explain করতে
- Weak object design identify করতে
- Encapsulation এবং invariants apply করতে
- Constructor এবং factory method-এর role distinguish করতে
staticএবং instance members সঠিকভাবে classify করতে==এবংequals()appropriateভাবে use করতে- Composition দিয়ে object relationships model করতে
- Immutable value object design করতে
- Package structure evaluate করতে
- ছোট domain model independently implement করতে
Part 1: Core Concepts Review
1. Class and Object
Class একটি type এবং object creation blueprint।
public class Course {
private String title;
}
Object:
Course course =
new Course();
একটি class থেকে multiple objects তৈরি করা যায়।
Course javaCourse =
new Course();
Course backendCourse =
new Course();
প্রতিটি object independent state রাখতে পারে।
2. Fields
Field object-এর state represent করে।
private String title;
private int totalLessons;
private boolean published;
Fields নির্বাচন করার সময় প্রশ্ন করুন:
- এটি কি object-এর own state?
- এটি কি অন্য object-এর state duplicate করছে?
- এটি কি derived value?
- এটি কি immutable হওয়া উচিত?
- এটি কি specific object-এর নাকি পুরো class-এর?
3. Methods
Method object-এর behavior বা query represent করে।
Command:
public boolean publish() {
published = true;
return true;
}
Query:
public boolean isPublished() {
return published;
}
Meaningful method object-এর domain intent express করে।
completeLesson()
cancel()
publish()
calculateProgress()
Weak names:
process()
handle()
update()
doSomething()
4. Parameters and Arguments
Parameter method declaration-এর input variable।
public boolean completeLessons(
int lessonCount
) {
}
Argument method call-এর actual value।
enrollment.completeLessons(
3
);
এখানে:
lessonCount → Parameter
3 → Argument
5. Return Values
Method result caller-এর কাছে ফেরত দিতে পারে।
public double calculateProgress() {
return completedLessons
* 100.0
/ totalLessons;
}
Caller result:
- Store করতে পারে
- Compare করতে পারে
- Print করতে পারে
- অন্য method-এ pass করতে পারে
- Test করতে পারে
6. Constructors
Constructor object creation-এর সময় valid initial state establish করে।
public Learner(
long id,
String name
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Learner ID must be positive."
);
}
if (
name == null
|| name.isBlank()
) {
throw new IllegalArgumentException(
"Learner name is required."
);
}
this.id = id;
this.name = name.strip();
}
Constructor-এর:
- Name class name-এর same
- কোনো return type নেই
newexpression-এর সময় execution হয়
7. The this Keyword
this current object reference করে।
this.title = title;
এখানে:
this.title → Object field
title → Constructor parameter
Constructor chaining:
Course(
String title,
int totalLessons
) {
this(
title,
totalLessons,
0
);
}
this() constructor body-এর first statement হতে হয়।
8. Encapsulation
Fields private রেখে state mutation controlled methods-এর মাধ্যমে করা হয়।
private int completedLessons;
External caller direct change করতে পারে না:
enrollment.completedLessons =
-100;
Meaningful operation:
enrollment.completeLessons(
3
);
9. Object Invariants
Invariant valid object-এর জন্য সবসময় true থাকা rule।
Enrollment invariants:
Completed lessons cannot be negative
Completed lessons cannot exceed total lessons
Cancelled enrollment cannot update progress
Completed enrollment cannot be cancelled
Constructor initial validity establish করে।
Methods future transitions-এর validity protect করে।
10. Static and Instance Members
Instance field specific object-এর state।
private String title;
Static field class-level shared state।
private static int totalCoursesCreated;
Constant:
public static final int MAX_TITLE_LENGTH =
150;
Specific object-এর domain state সাধারণত static হওয়া উচিত নয়।
11. Object References
Reference assignment object copy করে না।
Course secondReference =
firstReference;
দুই variables same object point করে।
এক reference দিয়ে mutation করলে অন্য reference থেকেও change দেখা যায়।
12. null
null মানে reference কোনো object point করছে না।
Course course = null;
Null reference দিয়ে method call:
course.publish();
Result:
NullPointerException
Required relationships constructor-এ enforce করলে null-related problems কমে।
13. Identity and Equality
== check করে দুই references same object point করছে কি না।
first == second
equals() logical equality define করতে পারে।
first.equals(second)
equals() override করলে hashCode()-ও override করতে হয়।
14. Composition
Object অন্য object reference করতে পারে।
public class Enrollment {
private final Learner learner;
private final Course course;
}
এটি has-a relationship।
Enrollment has a Learner
Enrollment has a Course
15. Immutability
Immutable object creation-এর পরে observable state change করতে দেয় না।
public final class CourseCode {
private final String value;
}
Immutable objects:
- Safely share করা যায়
- Equality stable রাখে
- Reason করা সহজ
- Concurrent read safer করে
16. Packages
Packages related code organize করে।
package io.liveklass.course;
Example structure:
io.liveklass.course
io.liveklass.learner
io.liveklass.enrollment
Feature-based packages domain ownership clear করে।
Part 2: Design Principles Review
Principle 1: Make Invalid States Difficult to Represent
Weak:
Course course =
new Course();
course.title = null;
course.totalLessons = -10;
Stronger:
Course course =
Course.freeCourse(
new CourseCode(
"JAVA"
),
"Java Foundation",
20
);
Invalid values constructor বা factory boundary-তে reject হয়।
Principle 2: Tell Objects What to Do
Weak:
enrollment.setCompletedLessons(
enrollment.getCompletedLessons()
+ 1
);
Better:
enrollment.completeLesson();
Caller object-এর internal state manipulation করছে না।
Caller meaningful intent express করছে।
Principle 3: Keep State and Rules Together
Rule:
Completed lessons cannot exceed total lessons.
এই rule Enrollment-এর কাছে থাকা উচিত।
public boolean completeLessons(
int lessonCount
) {
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> course.getTotalLessons()
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
Principle 4: Validate Before Mutating
Wrong:
completedLessons +=
lessonCount;
if (
completedLessons
> totalLessons
) {
return false;
}
Object ইতোমধ্যে invalid।
Correct:
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> totalLessons
) {
return false;
}
completedLessons =
updatedCount;
Principle 5: Avoid Duplicate Source of Truth
Weak:
class Enrollment {
private String courseTitle;
private int totalLessons;
}
যখন Course already owns those values।
Better:
private final Course course;
তবে historical snapshot intentional হলে copied data valid design হতে পারে।
Principle 6: Prefer Meaningful Operations over Blind Setters
Weak:
setActive(false);
setPublished(true);
setCompletedLessons(10);
Better:
cancel();
publish();
completeLessons(10);
Principle 7: Derived State Should Usually Be Calculated
Avoid:
private boolean completed;
private double progressPercentage;
যদি existing fields থেকে derive করা যায়:
public boolean isCompleted() {
return completedLessons
== course.getTotalLessons();
}
public double calculateProgress() {
return completedLessons
* 100.0
/ course.getTotalLessons();
}
Principle 8: Equality Is a Domain Decision
Course equality code-based হতে পারে।
return code.equals(
course.code
);
Money equality amount এবং currency-based হতে পারে।
Learner equality stable ID-based হতে পারে।
সব fields compare করাই universal rule নয়।
Principle 9: Use Composition for has-a
Correct:
class Enrollment {
private Course course;
}
Incorrect:
class Enrollment
extends Course {
}
Enrollment কোনো Course নয়।
Principle 10: Keep Public API Small
Every public method future callers-এর dependency হতে পারে।
Expose only meaningful operations।
publish()
cancel()
completeLesson()
calculateProgress()
Internal validation helper private রাখুন।
Part 3: Concept Check
প্রতিটি statement True না False নির্ধারণ করুন।
Question 1
A class and an object are the same thing.
Question 2
A constructor can have a void return type.
Question 3
Java passes object references by value.
Question 4
A private field can be accessed by methods inside the same class.
Question 5
Every private field should have a public setter.
Question 6
A static method has access to this.
Question 7
Reference assignment creates a new object.
Question 8
== compares logical object values by default.
Question 9
If equals() is overridden, hashCode() should also be overridden.
Question 10
A final reference guarantees deep immutability.
Question 11
Composition represents a has-a relationship.
Question 12
Two logically equal objects must be the same in-memory object.
Question 13
Package-private members are accessible from the same package.
Question 14
All validation should always be placed inside one domain object.
Question 15
A cancelled enrollment should reject progress updates if that is a domain invariant.
Concept Check Answers
Answer 1
False
Class type বা blueprint। Object সেই class-এর instance।
Answer 2
False
Constructor-এর কোনো return type নেই।
Answer 3
True
Object reference value-এর copy method-এ pass হয়।
Answer 4
True
private same class-এর ভেতরে accessible।
Answer 5
False
Setter শুধু meaningful এবং safe mutation প্রয়োজন হলে expose করা উচিত।
Answer 6
False
Static method কোনো specific object-এর ওপর execute হয় না।
Answer 7
False
Reference value copy হয়। New object তৈরি হয় না।
Answer 8
False
Objects-এর জন্য == reference identity compare করে।
Answer 9
True
Equal objects-এর same hash code থাকা প্রয়োজন।
Answer 10
False
Referenced object mutable হলে nested state change হতে পারে।
Answer 11
True
Answer 12
False
Separate objects logically equal হতে পারে।
Answer 13
True
Answer 14
False
Input validation, domain invariants এবং external rules different responsibilities হতে পারে।
Answer 15
True
Part 4: Predict the Output
Question 1: Shared Reference
Course first =
Course.freeCourse(
new CourseCode(
"JAVA"
),
"Java Foundation",
20
);
Course second =
first;
first.publish();
System.out.println(
second.isPublished()
);
Question 2: Separate Objects
CourseCode first =
new CourseCode(
"java"
);
CourseCode second =
new CourseCode(
"JAVA"
);
System.out.println(
first == second
);
System.out.println(
first.equals(second)
);
Question 3: Primitive Passing
static void change(
int value
) {
value = 100;
}
int number = 20;
change(number);
System.out.println(number);
Question 4: Reference Reassignment
static void replace(
Course course
) {
course =
Course.freeCourse(
new CourseCode(
"BACKEND"
),
"Backend Development",
30
);
}
Course course =
Course.freeCourse(
new CourseCode(
"JAVA"
),
"Java Foundation",
20
);
replace(course);
System.out.println(
course.getCode()
);
Question 5: Static State
Course.freeCourse(
new CourseCode(
"JAVA"
),
"Java",
20
);
Course.freeCourse(
new CourseCode(
"BACKEND"
),
"Backend",
30
);
System.out.println(
Course.getTotalCoursesCreated()
);
Assume counter starts at 0।
Question 6: Progress Validation
Enrollment enrollment =
Enrollment.enroll(
learner,
course
);
boolean first =
enrollment.completeLessons(
15
);
boolean second =
enrollment.completeLessons(
10
);
System.out.println(first);
System.out.println(second);
System.out.println(
enrollment.getCompletedLessons()
);
Assume course has 20 lessons।
Predict the Output Answers
Answer 1
true
Both variables same object reference করে।
Answer 2
false
true
References different, normalized values equal।
Answer 3
20
Primitive value-এর copy change হয়েছে।
Answer 4
JAVA
Method local reference reassign করেছে। Caller reference unchanged।
Answer 5
2
Both successful creations shared static counter increment করেছে।
Answer 6
true
false
15
Second update total lesson count exceed করত। State unchanged থাকে।
Part 5: Find the Bug
Bug 1: Constructor or Method?
public class Course {
void Course(
String title
) {
this.title =
title;
}
}
Problem
void থাকার কারণে এটি constructor নয়।
Fix
public Course(
String title
) {
this.title =
title;
}
Bug 2: Field Shadowing
public Learner(
String name
) {
name = name;
}
Problem
Parameter নিজের কাছে assign হচ্ছে।
Fix
public Learner(
String name
) {
this.name =
name;
}
Bug 3: Invalid Mutation Order
public boolean completeLessons(
int lessonCount
) {
completedLessons +=
lessonCount;
if (
completedLessons
> totalLessons
) {
return false;
}
return true;
}
Problem
Validation-এর আগে state mutate হয়েছে।
Fix
public boolean completeLessons(
int lessonCount
) {
if (lessonCount <= 0) {
return false;
}
int updatedCount =
completedLessons
+ lessonCount;
if (
updatedCount
> totalLessons
) {
return false;
}
completedLessons =
updatedCount;
return true;
}
Bug 4: Broken Encapsulation
public class Enrollment {
public int completedLessons;
public int totalLessons;
}
Problem
Caller arbitrary invalid state create করতে পারে।
Fix
public class Enrollment {
private int completedLessons;
private final int totalLessons;
public boolean completeLessons(
int lessonCount
) {
// Controlled state transition
}
}
Bug 5: Wrong Static Field
public class Enrollment {
private static int completedLessons;
}
Problem
সব enrollments same progress share করবে।
Fix
private int completedLessons;
Bug 6: String Comparison
if (
course.getCode()
.getValue()
== "JAVA"
) {
}
Problem
== String references compare করে।
Fix
if (
"JAVA".equals(
course.getCode()
.getValue()
)
) {
}
Better domain comparison:
if (
course.getCode()
.equals(
new CourseCode(
"JAVA"
)
)
) {
}
Bug 7: Missing hashCode()
@Override
public boolean equals(
Object other
) {
// Logical equality
}
Problem
hashCode() override করা হয়নি।
Fix
Equality fields ব্যবহার করে consistent hashCode() implement করুন।
Bug 8: False Immutability
public final class CoursePlan {
private final List<String> lessons;
public CoursePlan(
List<String> lessons
) {
this.lessons =
lessons;
}
public List<String> getLessons() {
return lessons;
}
}
Problem
Caller original list অথবা getter result mutate করতে পারে।
Fix
public CoursePlan(
List<String> lessons
) {
this.lessons =
List.copyOf(
lessons
);
}
public List<String> getLessons() {
return lessons;
}
Part 6: Code Review Exercise
নিচের class review করুন।
public class Enrollment {
public String learnerName;
public String courseTitle;
public static int completedLessons;
public int totalLessons;
public boolean active;
public Enrollment() {
}
public void setCompletedLessons(
int completedLessons
) {
Enrollment.completedLessons =
completedLessons;
}
public void update(
int value
) {
completedLessons +=
value;
}
public boolean completed() {
return completedLessons
>= totalLessons;
}
}
Problems to Identify
এই class-এ অন্তত নিচের problems আছে:
- Public fields
- Required state constructor-এ নেই
- Learner এবং course শুধু raw strings
completedLessonsincorrectly static- Total lessons validation নেই
- Blind setter
- Generic
update()name - Negative update accepted
- Total lessons exceed করা যায়
- Active state rule enforce হয় না
- Completion uses
>=, যা invalid over-completion hide করতে পারে - No encapsulation
- No composition
- No meaningful getters বা queries
- No cancellation behavior
- Object incomplete state-এ তৈরি হতে পারে
Improved Direction
public final class Enrollment {
private final Learner learner;
private final Course course;
private int completedLessons;
private boolean active;
private 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(
"Course must be published."
);
}
this.learner = learner;
this.course = course;
this.completedLessons = 0;
this.active = true;
}
public static Enrollment enroll(
Learner learner,
Course course
) {
return new Enrollment(
learner,
course
);
}
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 isCompleted() {
return completedLessons
== course.getTotalLessons();
}
}
Part 7: Design Judgment Questions
এই questions-এর একমাত্র universal answer নেই।
আপনার reasoning গুরুত্বপূর্ণ।
Question 1: Should Course Be Immutable?
Consider:
Course title may change
Course may be published
Price may change
Lessons may be added
Strong Answer
Entire Course immutable করার পরিবর্তে controlled mutable entity করা reasonable।
Stable parts immutable হতে পারে:
CourseCode
Course ID
Mutable transitions methods দিয়ে control করা যায়:
changeTitle()
publish()
addLesson()
Question 2: Should Learner Email Be the Identity?
Strong Answer
Email unique হতে পারে, কিন্তু change হতে পারে।
Stable generated learner ID সাধারণত stronger entity identity।
Email আলাদা immutable value object হতে পারে।
Question 3: Should Enrollment Store Course Title?
Strong Answer
Current dashboard-এর জন্য live Course reference enough হতে পারে।
Historical certificate, invoice, বা audit record-এর জন্য title snapshot প্রয়োজন হতে পারে।
Requirement অনুযায়ী সিদ্ধান্ত নিতে হবে।
Question 4: Should completeLessons() Return boolean?
Strong Answer
Simple caller-এর শুধু success বা failure জানা দরকার হলে boolean যথেষ্ট।
Failure reason দরকার হলে enum বা result object better।
UPDATED
INACTIVE
INVALID_COUNT
LIMIT_EXCEEDED
Question 5: Should Course Creation Use Constructors or Factories?
Strong Answer
One clear creation path থাকলে public constructor যথেষ্ট।
Multiple semantically different creation paths থাকলে static factory clearer হতে পারে:
Course.freeCourse(...)
Course.paidCourse(...)
Question 6: Should All Helpers Be Static?
Strong Answer
না।
Stateless calculation static হতে পারে।
Current object state-এর behavior instance method হওয়া natural।
External service calls static dependency করা testing এবং configuration কঠিন করতে পারে।
Question 7: Should Every Relationship Be Bidirectional?
Strong Answer
না।
Navigation প্রয়োজন না থাকলে unidirectional relationship simpler।
Bidirectional relationship consistency maintain করার cost আনে।
Question 8: Should Every Validation Throw an Exception?
Strong Answer
না।
Invalid object construction-এর জন্য exception appropriate হতে পারে।
Expected command rejection-এর জন্য boolean, enum, বা result object useful হতে পারে।
API request validation user-friendly error collection করতে পারে।
Part 8: Short Implementation Challenges
Challenge 1: Immutable EmailAddress
Create:
public final class EmailAddress
Rules:
- Required
- Blank নয়
- Spaces allowed নয়
@required- Lowercase normalize
- Value-based equality
- No setters
Challenge 2: Encapsulated Course
Fields:
CourseCode code
String title
int totalLessons
boolean published
Rules:
- Required values constructor-এ
- Title maximum 150
- Total lessons positive
- Published course title change করা যাবে না
- No blind setters
Challenge 3: Enrollment Progress
Implement:
boolean completeLesson()
boolean completeLessons(int count)
double calculateProgress()
int calculateRemainingLessons()
boolean isCompleted()
Rules:
- Inactive enrollment reject
- Count positive
- Total exceed নয়
- Validation before mutation
Challenge 4: Equality
For Learner:
id
name
email
Implement identity-based:
equals()
hashCode()
using id।
Challenge 5: Package Structure
Organize:
Course
CourseCode
Learner
Enrollment
Main
Root:
io.liveklass
Expected:
io.liveklass.course
io.liveklass.learner
io.liveklass.enrollment
io.liveklass
Part 9: Final Module Assessment
Section A: Multiple Choice
Question 1
কোন statement constructor সম্পর্কে correct?
A. Constructor must return void
B. Constructor name may be different from class name
C. Constructor has no return type
D. Constructor can only be private
Question 2
Objects-এর ক্ষেত্রে == কী compare করে?
A. All fields
B. Logical value
C. Hash codes
D. Reference identity
Question 3
কোনটি strong encapsulation?
A.
public int completedLessons;
B.
private int completedLessons;
public void setCompletedLessons(
int value
) {
completedLessons =
value;
}
C.
private int completedLessons;
public boolean completeLessons(
int count
) {
// Validate and update
}
D.
static int completedLessons;
Question 4
কোন field static হওয়া উচিত?
A. A learner's name
B. One enrollment's progress
C. Maximum course title length
D. One course's publication state
Question 5
কোন relationship composition?
A. Enrollment is a Course
B. Course has Lessons
C. Learner is an Enrollment
D. Course extends Enrollment
Question 6
final List<String> সম্পর্কে correct statement কোনটি?
A. List content কখনো পরিবর্তন করা যাবে না
B. Reference reassign করা যাবে না
C. List automatically deeply immutable
D. List automatically thread-safe
Question 7
কখন compiler default no-argument constructor দেয়?
A. Always
B. When all fields are private
C. When no constructor is declared
D. When class is final
Question 8
equals() override করলে আর কোন method override করা উচিত?
A. toString() only
B. clone()
C. hashCode()
D. finalize()
Section A Answers
1 → C
2 → D
3 → C
4 → C
5 → B
6 → B
7 → C
8 → C
Section B: Short Answers
Question 1
Encapsulation এবং immutability-এর difference কী?
Question 2
this.title = title explain করুন।
Question 3
Why is completedLessons an instance field?
Question 4
Why should a required Course relationship be checked in the Enrollment constructor?
Question 5
Why is CourseCode a good value object?
Question 6
Why should validation happen before assignment?
Question 7
Why can two separate Course objects be logically equal?
Question 8
Why is a static counter not suitable as a production database count?
Section B Suggested Answers
Answer 1
Encapsulation state access ও mutation control করে। Immutability creation-এর পরে observable state mutation prevent করে। Encapsulated object mutable হতে পারে।
Answer 2
Left side current object-এর title field। Right side current method বা constructor parameter।
Answer 3
প্রতিটি enrollment-এর progress আলাদা। Static করলে সব enrollments same value share করত।
Answer 4
Object complete এবং valid state-এ তৈরি হয়, repeated null checks কমে, এবং missing course early reject হয়।
Answer 5
Course code stable, validated, normalized, identity-like value। Value change হলে নতুন code represent করে।
Answer 6
Invalid state object-এর মধ্যে commit হওয়া prevent করতে।
Answer 7
তারা same stable identity, যেমন same CourseCode, represent করতে পারে।
Answer 8
Static field process-local, non-persistent, restart-sensitive, multi-server unaware এবং automatically thread-safe নয়।
Section C: Refactoring Task
Refactor:
public class Course {
public String code;
public String title;
public int totalLessons;
public boolean published;
public Course() {
}
public void setPublished(
boolean published
) {
this.published =
published;
}
}
Your refactored class should:
- Use an immutable
CourseCode - Validate title
- Validate total lessons
- Hide fields
- Provide a meaningful
publish()operation - Prevent repeated publication
- Expose appropriate queries
- Avoid a no-argument constructor
One Possible Solution
public final class Course {
private final CourseCode code;
private final String title;
private final int totalLessons;
private boolean published;
public Course(
CourseCode code,
String title,
int totalLessons
) {
if (code == null) {
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 positive."
);
}
this.code = code;
this.title = title.strip();
this.totalLessons =
totalLessons;
this.published = false;
}
public boolean publish() {
if (published) {
return false;
}
published = true;
return true;
}
public CourseCode getCode() {
return code;
}
public String getTitle() {
return title;
}
public int getTotalLessons() {
return totalLessons;
}
public boolean isPublished() {
return published;
}
}
Part 10: Self-Evaluation Rubric
নিজের solution 0–2 scale-এ evaluate করুন।
0 = Missing or incorrect
1 = Partially correct
2 = Correct and clearly designed
| Area | Score |
|---|---|
| Classes have focused responsibilities | /2 |
| Required state constructors enforce করে | /2 |
| Fields appropriately private | /2 |
| Blind setters avoided | /2 |
| Invariants protected | /2 |
| Validation before mutation | /2 |
| Static members used appropriately | /2 |
| Equality intentionally designed | /2 |
| Composition used for relationships | /2 |
| Immutable values safely designed | /2 |
| Package structure clear | /2 |
| Method names reveal intent | /2 |
| Derived state calculated | /2 |
| Null handling intentional | /2 |
| Public API small and meaningful | /2 |
Maximum:
30
Interpretation:
26–30 → Strong understanding
21–25 → Good foundation, minor gaps
15–20 → Concepts understood but design practice needed
Below 15 → Revisit lessons and rebuild the practice project
Final Reflection
Strong OOP code বেশি getters, setters, বা classes তৈরি করার নাম নয়।
Strong OOP code চেষ্টা করে:
State-এর clear owner নির্ধারণ করতে
Business rules state-এর কাছে রাখতে
Invalid transitions prevent করতে
Meaningful operations expose করতে
Implementation details hide করতে
Relationships accurately model করতে
Weak object design caller-কে বলে:
এই fields নিন এবং নিজে ঠিকভাবে manipulate করার চেষ্টা করুন।
Strong object design caller-কে বলে:
এই meaningful operations ব্যবহার করুন।
Object নিজের rules নিজে protect করবে।
Module Summary
এই module-এ আমরা শিখেছি:
- Class একটি type এবং object creation blueprint
- Objects independent state carry করে
- Fields object state represent করে
- Methods behavior এবং queries express করে
- Parameters input গ্রহণ করে
- Return values reusable result দেয়
- Constructors valid initial state establish করে
thiscurrent object reference করে- Constructor chaining duplication কমায়
- Method overloading carefully use করতে হয়
- Encapsulation internal state protect করে
- Blind setters object invariants দুর্বল করে
- Invariants object lifetime-এর validity define করে
- Instance members object-specific
- Static members class-level
- Static mutable state production complexity তৈরি করতে পারে
- References object access path represent করে
- Reference assignment object copy করে না
nullobject absence represent করে==reference identity compare করেequals()logical equality define করতে পারেhashCode()equality contract-এর অংশtoString()debugging representation দেয়- Composition
has-arelationships model করে - Duplicate data consistency risk তৈরি করতে পারে
- Historical snapshots intentional duplication হতে পারে
- Immutable value objects safely share করা যায়
finaldeep immutability guarantee করে না- Defensive copying mutation leaks prevent করে
- Packages code ownership এবং organization communicate করে
- Feature-based organization maintainability improve করতে পারে
- Good object design syntax-এর চেয়ে responsibility এবং rules-এর ওপর বেশি depend করে
Module Completion Checklist
Module 2 complete করার আগে নিশ্চিত করুন আপনি পারবেন:
- একটি class এবং object explain করতে
- Constructor লিখতে
- Constructor validation implement করতে
-
thiscorrectly ব্যবহার করতে - Fields
privateকরতে - Meaningful command methods design করতে
- Object invariants define করতে
- Static এবং instance members classify করতে
- Object reference sharing explain করতে
-
nullsafely handle করতে -
==এবংequals()distinguish করতে -
equals()এবংhashCode()implement করতে - Composition দিয়ে relationships model করতে
- Immutable value object তৈরি করতে
- Mutable state defensiveভাবে expose করতে
- Package structure design করতে
- একটি small domain model independently build করতে
Next Module
পরবর্তী module:
Inheritance, Interfaces, and Polymorphism
আমরা শিখব:
- Inheritance কী
extends- Parent এবং child classes
- Method overriding
super- Abstract classes
- Interfaces
- Polymorphism
- Dependency inversion-এর foundation
- Composition vs inheritance
- When inheritance helps
- When inheritance creates fragile design