Class Organization
Classes should be small, focused, and have a single reason to change.
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.
🔧 Some exercises may still have errors. If something seems wrong, use the Feedback button (bottom-right of the page) to report it — it helps us fix it fast.
Hint: List every method in the class, then group them by what data they operate on. Methods that only touch the same fields naturally belong together. Groups that touch *different* fields are telling you where to split.
✗ Your version