Card 07/ 08

ExerciseDifficulty: Intermediate1 min

Practice: Splitting a User Account Class

Sign-up rules, password hashing, a welcome email and a CSV export in one class.

Splitting a class by reason to change starts with naming its actors. This exercise gives you a UserAccount class from a sign-up service. First list the groups of people who could ask for each part to change, then propose the classes you would split it into.

py
import hashlib


class UserAccount:
    def __init__(self, email, password):
        if "@" not in email:
            raise ValueError("invalid email")
        if len(password) < 8:
            raise ValueError("password too short")
        self.email = email
        self.password_hash = hashlib.sha256(password.encode()).hexdigest()

    def send_welcome_email(self):
        print(f"MAIL to {self.email}: Welcome aboard!")

    def to_csv_row(self):
        return f"{self.email},{self.password_hash[:8]}"


account = UserAccount("[email protected]", "correct horse")
account.send_welcome_email()
print(account.to_csv_row())
OutputRan with python:3.12-slim (Python 3.12.13)
MAIL to [email protected]: Welcome aboard!
[email protected],4104d36f
One class that validates, hashes, emails and exports.

Work through it in two passes. For every method and every check inside the constructor, write down who would ask for it to change. Then group the pieces by those names; each group is a candidate class. Check that nothing you put together would ever change for two different groups.

Show one good answer
The parts of UserAccount, who asks for changes, and where each part goes
PartActorNew home
Email must contain @Product team (sign-up rules)SignUpRules
Password at least 8 charactersSecurity teamPasswordPolicy
SHA-256 hashingSecurity teamPasswordPolicy
Welcome email textMarketing teamWelcomeMailer
CSV export columnsData teamAccountCsvExport

Four actors means four classes, plus a plain UserAccount that only holds the email and the hash. The password length rule and the hashing go together even though they are different methods, because the security team changes both. (Plain SHA-256 is also too fast for real passwords; that would be the security team's first change.)

UserAccount after the split