Object-Oriented Programming Foundations

Module Review and Assessment

ReadingPreview

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 নেই
  • new expression-এর সময় 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 আছে:

  1. Public fields
  2. Required state constructor-এ নেই
  3. Learner এবং course শুধু raw strings
  4. completedLessons incorrectly static
  5. Total lessons validation নেই
  6. Blind setter
  7. Generic update() name
  8. Negative update accepted
  9. Total lessons exceed করা যায়
  10. Active state rule enforce হয় না
  11. Completion uses >=, যা invalid over-completion hide করতে পারে
  12. No encapsulation
  13. No composition
  14. No meaningful getters বা queries
  15. No cancellation behavior
  16. 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
AreaScore
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 করে
  • this current 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 করে না
  • null object absence represent করে
  • == reference identity compare করে
  • equals() logical equality define করতে পারে
  • hashCode() equality contract-এর অংশ
  • toString() debugging representation দেয়
  • Composition has-a relationships model করে
  • Duplicate data consistency risk তৈরি করতে পারে
  • Historical snapshots intentional duplication হতে পারে
  • Immutable value objects safely share করা যায়
  • final deep 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 করতে
  • this correctly ব্যবহার করতে
  • Fields private করতে
  • Meaningful command methods design করতে
  • Object invariants define করতে
  • Static এবং instance members classify করতে
  • Object reference sharing explain করতে
  • null safely 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