ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SOLID
    CS(ComputerScience) 2020. 12. 3. 17:05

    안녕하세요. 그린입니다!

    오늘은 SOLID에 대해 학습한 부분을 공유해보며 생각을 정리해보겠습니다..!

    SOLID가 뭘까요 도대체??

    스위프트는 객체지향 언어인건 다들 아실겁니다.

     

    SOLID를 개괄적으로 정리하자면 객체지향프로그래밍을 위한 5가지 원칙!! 이라고 표현할 수 있습니다.

    SOLID는 어떻게보면 프로그래밍을 하기위한 디자인 패턴과 같이 어떠한 약속? 이라고 생각됩니다.

    누구나 보기 편하고 단순하며 확장성이 있는 프로그래밍을 하는것이 중요하다고 모든 프로그래머들은 생각합니다.

    그렇기 위해서 디자인 패턴이던 MVC 모델이던 있다고 생각들죠? 그런것과 SOLID의 관념은 유사하다고 생각듭니다.

     

    그러면 이제 SOLID가 5가지 원칙이라면 어떤 5가지를 나타내는지 이제 알아보겠습니다~!

     

    1. SRP (Single-Responsibility Principle) - 단일 책임 원칙

     : 한 클래스는 단 한가지의 책임만 가진다.

    제가 생각해볼때는 이렇게 생각이 듭니다. 한 클래스가 여러 객체에서 책임을 진다면 무언가를 변경해야될 사항이 생기면

    여러 부분을 뜯어 고쳐야합니다. 예를들어 같이 협업을 하고 있다는 가정하에 공통된 클래스를 가져와서 서로 다른 부분을

    구현하고 있습니다. 그런데 만약 A파트에서 기획이 변경되어 해당 클래스의 어떠한 부분의 추가나 변경이 이뤄져야한다면

    B파트는 난감할겁니다. 이렇게 클래스를 응집도가 있는 것끼리 최소한으로 책임을 갖게해야 합니다.

     

    2. OCP (Open-Close Principle) - 개방/폐쇄 원칙

     : 확장이 가능하도록 개방되어있고 변경에는 폐쇄적이여야한다.

    만약 새로운 기능이 추가된다면 기존에서 변경하거나 추가하지말고 새로운 클래스나 메서드를 생성하여 추가해주는것이 좋습니다.

    다른것을 건드리지않고 코드의 추가만으로 확장에 용이하며 변경에는 폐쇄적이 됩니다.

    예를들어, 프로토콜과 열거형이 있습니다.

    프로토콜로 구현한 코드에서 추후 어떠한 타입이나 메서드/프로퍼티가 추가될때는 과연 어떨까요?

     

    [프로토콜]

    -. 타입추가

    protocol Punch { }
    struct SoftPunch: Punch { }
    struct HardPunch: Punch { }

    이렇게 있을때, 어떤 냥냥펀치라는 새로운 펀치의 타입을 확장해주고 싶다면 간단하게

    struct CatPunch: Punch { }

    처럼 한 줄의 코드만으로 확장을 시키며 프로토콜의 내부 변경이나 다른 구조체의 변경이 이뤄지지 않습니다.

    -. 메서드/프로퍼티 추가

    protocol Punch {    
    	func left()    
    	func right()
    }

    이러한 프로토콜이 존재할때 프로토콜안에서 어떠한 메서드와 프로퍼티를 넣어주게 된다면 프로토콜을 채택한

    소프트/미들/냥냥펀치의 메서드 안에서도 구현을 일일히 해주면서 코딩을 해야하는 번거로움이 있습니다.

    이 부분은 확장에는 용이하지 않고 변경이 이뤄지기에 OCP원칙에 위배됩니다.

    이렇게 보자면 프로토콜은 메서드/프로퍼티 추가보다는 타입을 추가할때 용이하다고 볼 수 있습니다.

     

    [열거형]

    그 다음으로, 열거형 (enum)을 보겠습니다.

    열거형은 프로토콜과 반대의 성향을 가집니다. 아래 살펴보겠습니다.

    -. 타입추가

    enum Punch {    
    	case softPunch    
    	case hardPunch    
    	func left()    
    	func right()
    }

    이럴경우 만약 또 냥냥펀치의 타입이 필요할경우 위 코드에서 left/ right 메서드의 해당 케이스를 다 넣어주어야 하는

    귀찮음이 발생합니다. OCP에 위배되죠? 그러면 메서드/프로퍼티 추가일때는 어떨까요?

    -. 메서드/프로퍼티 추가

    enum Punch {    
    	case softPunch    
    	case hardPunch    
    	func left()    
    	func right()
    }

    이럴때 막기라는 동작의 메서드를 구현할때 프로토콜에서는 채택한 모든 구조체에 대해 일일히 코딩을 해줬다라하면

    열거형에서는 위의 코드에서 해당 구현할 메서드를 추가해주기만 하면 됩니다.

    즉, 다시한번 정리하면 프로토콜: 타입추가 / 열거형: 메서드,프로퍼티 추가 시 OCP를 위배하지 않는다고 할 수 있습니다!!!

     

    3. LSP (Liskov Substitution Principle) - 리스코프 치환 원칙

     : 자식클래스가 부모클래스로의 역할을 다 수행해야한다.

    리스코프?? 말만들어도 어렵죠? 그렇습니다. 사람이름이고 아직도 조금 헷갈리는 5가지 원칙중 하나입니다 ㅠㅠ

    조금 쉽게 말한다면 "상위 타입 객체를 하위 타입 객체로 치환해도 상위 타입을 사용하는 기능이 정상적이여야 한다" 라고 말할 수 있을것

    같습니다. 음 아직도 감이 잘 안오죠? 상속과 관련이 있는것 같기도하고 부모클래스의 모든 부분을 그대로 구현해줘야하나 싶기도하고..

    한번 조금 더 자세히 알아보시죠!

    만약 펀치의 메서드중 왼쪽 펀치라는 기능을 가진 클래스를 냥냥펀치가 상속 받았다고 생각해보면,

    냥냥펀치의 왼쪽 펀치 메서드의 기능을 왼쪽 발차기로 변경했다하면 오류가 난다는 것이다.

    냥냥펀치를 부모인 펀치로 대입했을때 되지 않기 때문이다.

    조금 이해가 안간다면 직사각형/정사각형에 관해 더 자세히 나온것들이 많으니 예제를 참고해보면 좋을것 같습니다 ^^

     

    4. ISP (Interface Segregation Principle) - 인터페이스 분리 법칙

     : 인터페이스는 최대한 작게 가져가야한다.

    불필요한 메서드를 구현할 필요가 없습니다. 불필요한 메서드를 받아오는 쪽에서는 구현하지 않게되면 텅 빈 구현이 되기때문입니다.

    이것이 제일 저는 와닿았습니다. 코딩을 하다보면 어느 단위로 쪼갤지 어떤 기능 메서드로 나눌지 생각이 들죠!?

    그런것과 마찬가지로 인터페이스 분리 법칙을 생각해보면 좋을것 같아요!

     

    5. DIP (Dependency Inversion Priciple) - 의존성 역전 원칙

     : 상위수준 모듈은 하위수준 모듈에 의존하면 안된다.

    구체적 사항은 추상화에 의존해야한다. 인데.. 음 구체적인것은 변하기 쉽지만 추상적인것은 개념이라던지 그런것들이 변할 그런게 적으니까

    그런것같다고 생각합니다. 설명이 조금 너무 난해하긴한데... 음.. 간단히 최대한 간단히 생각해보면!

    상위모듈보다 하위모듈이 더 쉽게 변하니까 거기에 의존하지 말라는 뜻이라 생각합니다.

     

    오늘 포스팅은 이렇게 SOLID의 개념적인 부분에 대해 다뤄봤습니다!

    추가되야 하거나 변경될 부분들은 가감없이 말씀해주시면 좋겠습니다~!!

    감사합니다!

     

    'CS(ComputerScience)' 카테고리의 다른 글

    Cache  (0) 2021.02.04
    HTTP & TCP/IP  (0) 2021.01.18
    OS와 Process  (0) 2021.01.05
    자료구조와 알고리즘  (0) 2020.12.08
    컴퓨터과학 기초  (0) 2020.11.05
Designed by Tistory.