Skip to main content
Clean Code 70 XP · 7 min

Class Organization

Classes should be small, focused, and have a single reason to change.

Showing
Ad (728×90)

Internal Organization

Standard ordering inside a class: (1) public static constants, (2) private static variables, (3) private instance variables, (4) public methods, (5) private helpers called by each public method, placed immediately after it. This creates a top-down read: public contract first, implementation details below.

Random order — private detail first

class InvoiceService:
    function _formatAmount(amount):
        return "$" + formatDecimal(amount, 2)

    function _calculateTax(subtotal):
        return subtotal * 0.08

    STANDARD_TAX_RATE = 0.08  // ← buried

    function generate(order):  // ← hard to find
        tax   = _calculateTax(order.subtotal)
        total = order.subtotal + tax
        return "Invoice: " + _formatAmount(total)

Standard order — public contract on top

class InvoiceService:
    STANDARD_TAX_RATE = 0.08   // 1. constants

    function generate(order):  // 2. public
        tax   = _calculateTax(order.subtotal)
        total = order.subtotal + tax
        return "Invoice: " + _formatAmount(total)

    function _calculateTax(subtotal):  // 3. private helpers
        return subtotal * STANDARD_TAX_RATE

    function _formatAmount(amount):
        return "$" + formatDecimal(amount, 2)

The Single Responsibility Principle

A class should have one reason to change. Not one method — one responsibility. Ask: "If I describe this class in one sentence, does it need the word and?" If yes, split it. A UserManager that handles authentication, profile updates, email notifications, and audit logging has four reasons to change. Split it into four focused classes.

God Class — does everything user-related

class UserManager:
    // Authentication
    function login(email, password): ...
    function logout(sessionId): ...
    function resetPassword(email): ...
    // Profile
    function updateName(userId, name): ...
    function uploadAvatar(userId, file): ...
    // Notifications
    function sendWelcomeEmail(user): ...
    function sendPasswordResetEmail(user): ...
    // Audit
    function logLoginAttempt(email, ok): ...
    function logProfileChange(uid, field): ...

Four focused classes, one reason each to change

class AuthService:
    function login(email, password): ...
    function logout(sessionId): ...
    function resetPassword(email): ...

class UserProfileService:
    function updateName(userId, name): ...
    function uploadAvatar(userId, file): ...

class UserNotificationService:
    function sendWelcome(user): ...
    function sendPasswordReset(user): ...

class UserAuditLog:
    function recordLogin(email, ok): ...
    function recordProfileChange(uid, field): ...

Cohesion and Change

High cohesion means every method uses most of the class's instance variables. When you notice a group of methods only uses a subset of instance variables, that's a class hiding inside your class — extract it. Classes should be open for extension, closed for modification: new behavior = new class, not editing existing code.

Low cohesion — two classes hiding in one

class ReportGenerator:
    data   = []      // ─┐ data fields
    source = null    // ─┘
    font   = "Arial" // ─┐ formatting fields
    margin = 20      // ─┘

    function fetchData(): ...   // uses data, source
    function filterData(): ...  // uses data
    function setFont(f): ...    // uses font
    function setMargin(m): ...  // uses margin
    function renderPdf(): ...   // uses font, margin

High cohesion — extract the hidden class

class DataFetcher:
    source = null
    data   = []

    function fetch(): ...
    function filter(predicate): ...

class PdfRenderer:
    font   = "Arial"
    margin = 20

    function render(data): ...

Code Challenge

Identify and Split the God Class — use the 'and' test. If you need 'and' to describe the class, split it.

Key takeaway

If you need 'and' to describe your class, it has more than one responsibility. Split it until each class has a single reason to exist.

Done with this lesson?

Mark it complete to earn XP and track your progress.