클래스

단일 책임 원칙(SRP) 지키기

  • 하나의 클래스는 하나의 책임만 갖도록 설계한다.

  • 클래스도 작아야 가독성과 유지보수 측면에 이점이 있다.

// as-is
class Store {                 // Store 클래스가 많은 역할을 혼자 수행한다.
    func cummunicateUser() { }
    func manageProducts() { }
    func manageMoney() { }
}
// to-be
class CounterManager {
    func communicateUser() { }
}

class ProductManager {
    func manageProducts() { }
}

class Owner {
    func manageMoney() { }
}

class Store {
    let counterManager: CounterManager
    let productManager: ProductManater
    let owner: Owner

    func sellProduct() {
        counterManager.communicateUser()
        // code
    }
    // code...
}

응집도를 높이자.

  • 응집도는 클래스의 변수와 메서드가 얼마나 유기적으로 엮여있는지를 나타내는 지표이다.

    • 응집도가 높을수록 클래스의 메서드는 인스턴스 변수를 많이 사용한다.

    • 응집도가 낮을수록 클래스의 메서드는 인ㅅ턴스 변수를 적게 사용하거나 사용하지 않는다.

// as-is

class LowCohension {
    var a: Int
    var b: Int
    var c: Int

    func processA() {
        print(self.a)
    }

    func processB() {
        print(self.b)
    }

    func processC() {
        print(self.c)
    }
}
// to-be
class HighCohension {
    var abc: ABC

    func processA() {
        print(self.abc.processA())
    }

    func procesB() {
        print(self.abc.processB())

    func procesC() {
        print(self.abc.processC())
}
// 실제 코드, element인스턴스가 3개의 메서드에서 모두 사용되고 있다.
class Stack { 
    var elements = [Int]()

    func size() -> Int {
        return elements.count
    }

    func push(_ element: Int) {
        elements.append(element)
    }

    func pop() -> Int? {
        guard !elements.isEmpty else { return nil }
        return elements.removeLast()
    }
}

변경하기 쉽게 만들자 (open closed)

  • 다형성과 연결되는 부분이다.

  • 새 기능을 수정하거나 기존 기능을 변경할 때, 코드의 변경으 최소화하는 것이 중요하다.

  • 일반적으로 클래스(객체)는 구현과 추상으로 나뉜다.

    • 구현(Concrete) : 실제 동작하는 구체적 코드

    • 추상 (Abstract) : 구체적인 기능을 개념화한 코드

  • 변경하기 쉽게 설계하기 위해서, 추상화를 통해 구체 클래스에 의존하지 않고, 추상 클래스에 의존하도록 코드를 작성하는 것이 중요하다.

    // as-is
    class Developer {
        func coding() {
            print("코딩을 합니다")
        }
    }
    
    class Designer {
        func design() {
            print("디자인을 합니다")
        }
    }
    
    class Analyst {
        func analyze() {
            print("분석을 합니다")
        }
    }
    
    class Company {
        var employees = [Employee]
    
        func makeWokr() {
            for employee in employess {
                switch employee {
                case .developer:
                    employee.coding()
                case .designer:
                    employee.disign()
                case .analyst:
                    employee.analyze()
                }
            }
        }
    }
    // to-be
    protocol Employee {
        func work()
    }
    
    class Company {
        var employees = [Employee]
    
        func makeWork() {
            for employee in employees {
                employee.work()
            }
        }
    }
    
    class Developer: Employee {
        func work() {
            print("coding")
        }
    }
    
    class Designer: Employee {
        func work() {
            print("design")
        }
    }

Last updated