Clean Code - Class

Single Responsibility Principle (SRP)

一個模組應只對唯一一個使用者或利益相關者負責。

Bad

from importlib import metadata

class VersionCommentElement:
     """An element that renders an HTML comment with the program's version number
     """

     def get_version(self) -> str:
          """Get the package version"""
          return metadata.version("pip")

     def render(self) -> None:
          print(f'<!-- Version: {self.get_version()} -->')

VersionCommentElement().render()

Good

from importlib import metadata

def get_version(pkg_name: str) -> str:
     """Retrieve the version of a given package"""
     return metadata.version(pkg_name)

class VersionCommentElement:
     """An element that renders an HTML comment with the program's version number
     """

     def __init__(self, version: str):
          self.version = version

     def render(self) -> None:
          print(f'<!-- Version: {self.version} -->')

VersionCommentElement(get_version("pip")).render()

Open-Close Principle (OCP)

可以在不修改現有的原始碼的前提下,變更他的行為或實作新的功能。

Liskov Substitution Principle (LSP)

子型態必須遵從父型態的行為進行設計。

Interface Segregation Principle (ISP)

模組與模組之間的依賴,不應該有用不到的功能可以被對方呼叫

Dependency Inversion Principle (DIP)

高層模組不應依賴底層模組,他們都應該依賴於抽象介面。抽象介面不應該依賴於具體實作,具體實作應依賴抽象介面。

Don’t repeat yourself (DRY)

Bad:

from typing import List, Dict
from dataclasses import dataclass

@dataclass
class Developer:
    def __init__(self, experience: float, github_link: str) -> None:
        self._experience = experience
        self._github_link = github_link

    @property
    def experience(self) -> float:
        return self._experience

    @property
    def github_link(self) -> str:
        return self._github_link

@dataclass
class Manager:
    def __init__(self, experience: float, github_link: str) -> None:
        self._experience = experience
        self._github_link = github_link

    @property
    def experience(self) -> float:
        return self._experience

    @property
    def github_link(self) -> str:
        return self._github_link

def get_developer_list(developers: List[Developer]) -> List[Dict]:
    developers_list = []
    for developer in developers:
        developers_list.append({
            'experience': developer.experience,
            'github_link': developer.github_link
        })
    return developers_list

def get_manager_list(managers: List[Manager]) -> List[Dict]:
    managers_list = []
    for manager in managers:
        managers_list.append({
            'experience': manager.experience,
            'github_link': manager.github_link
        })
    return managers_list

## create list objects of developers
company_developers = [
    Developer(experience=2.5, github_link='<https://github.com/1>'),
    Developer(experience=1.5, github_link='<https://github.com/2>')
]
company_developers_list = get_developer_list(developers=company_developers)

## create list objects of managers
company_managers = [
    Manager(experience=4.5, github_link='<https://github.com/3>'),
    Manager(experience=5.7, github_link='<https://github.com/4>')
]
company_managers_list = get_manager_list(managers=company_managers

Good:

from typing import List, Dict
from dataclasses import dataclass

@dataclass
class Employee:
    def __init__(self, experience: float, github_link: str) -> None:
        self._experience = experience
        self._github_link = github_link

    @property
    def experience(self) -> float:
        return self._experience

    @property
    def github_link(self) -> str:
        return self._github_link

def get_employee_list(employees: List[Employee]) -> List[Dict]:
    employees_list = []
    for employee in employees:
        employees_list.append({
            'experience': employee.experience,
            'github_link': employee.github_link
        })
    return employees_list

## create list objects of developers
company_developers = [
    Employee(experience=2.5, github_link='<https://github.com/1>'),
    Employee(experience=1.5, github_link='<https://github.com/2>')
]
company_developers_list = get_employee_list(employees=company_developers)

## create list objects of managers
company_managers = [
    Employee(experience=4.5, github_link='<https://github.com/3>'),
    Employee(experience=5.7, github_link='<https://github.com/4>')
]
company_managers_list = get_employee_list(employees=company_managers)

Click here to share this article with your friends on X if you liked it.