일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 이름
- protocol
- IOS
- 문법
- Solid
- 인터페이스
- 아이폰프로그래밍
- 의도
- 의존성
- fp
- 함수형패러다임
- 개발
- OOP
- 부스트코스
- DesignPattern
- 개발자
- 협업
- SWIFT
- Swfit
- 객체지향프로그래밍
- 클린코드
- interface
- iOS프로그래밍
- 함수형프로그래밍
- POP
- 고차함수
- CleanCode
- 디자인패턴
- 클린소프트웨어
- 네이밍
- Today
- Total
목록OOP (12)
밤에 쓴 코드
객체의 지도 객체를 설계함에 있어서 어떤 고민을 해볼 지 생각해 보자 기능과 구조 지금 부엉이가 친구 병아리를 만나려고 한다. 그래서 병아리는 부엉이에게 자신의 위치를 알려준다. ➡️ 으로 2블럭 ⬆️ 으로 2블럭 이렇게 위치를 설명해 주었다. 이렇게 집을 찾을 수 있었다. 그런데 만약 부엉이가 시작점이 변경된다면? 과연 위에 길안내는 유효할 것인가? ➡️ 으로 1블럭 ⬆️ 으로 2블럭 으로 길 안내가 변경 되었다. 부엉이(사용자)가 위치설명(목표)를 위해 요청 했을 때, 부엉이의 위치(사용자의 상황-요구사항) 에 따라서 절차(기능)들이 변경되었다. 이처럼 특정 요구사항 마다 , 기능들이 변경되었다, 하지만 구조적으로 접근을 했다면, 다른 결과를 얻을 수 있다. 부엉이에게 이런 지도(구조)를 손에 쥐어 ..
ISP- 인터페이스 분리 법칙 (Interface segregation principle) 클래스 내에서 사용하지 않는 인터페이스는 구현하지 말아야 한다. DIP 에서 만들어진 고양이가 잘 이동하고 있다 . DIP - 의존관계 역전법칙(Dependency inversion Principle) 강아지도 추가해서 , 이쁘게 움직이게 만들어 주었다. 그런데 어느날 '달팽이'가 필요해졌다. struct 달팽이(){ let 움직이기전략: 움직이는방법 // 구체적이지 않은 클래스에 의존 func 이동하기(){ 움직이기전략.이동하다() } //DI - 의존성주입 mutating func 움직이는방법바꾸기(_ 새로운움직이기전략:움직이는방법){ self.움직이기전략 = 새로운움직이기전략 } }struct ..
DIP - 의존관계 역전법칙(Dependency inversion Principle) 추상화 된 것은 구체적인 것에 의존하면 안되고 구체적인 것이 추상화된 것에 의존해야 한다 위에서는 변할수 있는것 과 변하지 않을 것 을 나누는 게 중요했다. 그리고 구체적일 수록 잘 변했고 , 구제적이지 않을 수록 잘 변하지 않았다. 객체사이의 서로 도움을 주고 받으면서 협력을 하게 되면 어쩔수 없이 의존관계가 생길 수밖에 없다. struct 평범한움직임{ func 이동하다() { print("🐾") } func 점프하다() { print("💨") } } struct 고양이 { let 움직이는전략: 평범한움직임 // 구체 클래스 func 이동하기(){ 움직이는전략.이동하다() } func 점프하기(){ 움직이는전략.점프..
LSP - 리스코프 치환 원칙 (Liskov substitution principle) 자식클래스 (서브클래스) 는 부모클래스(슈퍼클래스)의 역할을 완벽히 수행할 수 있어야한다. 호오 당연한 얘기 아닌가? '새'를 상속받은 '부엉이는 '새'로써의 역할을 완벽히 해야한다. 맞는 말인데 이게 좀 처럼 지켜지지 않는다. 이 문제는 서브클래스가 슈퍼클래스의 메소드를 Override 하는 과정에서 발생한다. class 초시계 { var 초:Int = 0 func 시간이흐르다(){ 초 = 초 == 59 ? 0 : 초 + 1 } func 시간보여주기(){ print("\(초)초") } } 초시계를 만들어 보았다. 근데 초시계의 동작을 모두 수행하면서 분까지 보고싶은 마음에 , 분초..
OCP -개방폐쇄 원칙 (Open-closed principle) 확장에 개방적이고 , 변경에 폐쇄적이어야한다. 음? 처음에 확장과 변경이 그렇게 다른 것인지 의문을 가졌었다. 일단 확장은 기능의 추가이고 , 변경은 기능구현의 변경이다. 기능을 추가할때는 딱 기능만 추가할 수 있게 , 즉 기존의 다른 부분들에 수정이 필요 없게 , 기능이 변경이 , 이 기능을 가져다 쓰는 다른 코드들에 영향을 주지않게 해야한다는 것이다. 개발을 접하지 않은 사람들이 보기에 어찌보면 당연하게 들릴 것이다. 기능을 추가하면 기능만 추가 되면 그만이지. 변경되면 변경만 되면 그만이지 라고 생각 할 수 있다 . 이 과정은 생각보다 쉽지 않다 . 하지만 우리는 저 어렵지만 당연한 생각 을 실천해야한다. 변경에 폐쇄적이려면 어떻게 ..
SRP -단일 책임 원칙 (Single responsibility principle) 하나의 클래스는 하나의 책임을 가져야한다. 클래스내부의 코드들은 서로 강하게 결합이 되게된다 . 두개의 서로 다른 책임을 가지게 된다면 , 서로 관련성이 없는 두 코드들이 강하게 결합될 수 있는 것이다. 또 , 여러개의 책임을 가지고 있다면 , 변경에 따른 테스트의 갯수 또한 많아지게 될 것이다. 여러개의 책임을 가진 구조체 struct IT기업 { func 소프트웨어만들기() -> 검증된소프트웨어? { let 설계도 = 설계하기() let 프로토타입 = 개발하기(설계도: 설계도) let 시제품 = 테스트하기(대상: 프로토타입) ? 프로토타입 : nil return 시제품 } func 설계하기() -> 시스템다이어그램 ..
SOLID - 객체 지향 5 원칙 나쁜설계는 변경에 취약한 소프트웨어를 만든다 나쁜소프트웨어는 디른 곳에 영향을 주어서 A기능 수정이 B기능까지 영향을 주어 , 갑자기 엉뚱한 곳이 망가질 수있고 , 그에 따른 연쇄되는 수정이 동반되어야 할것이다. 또 서로 연관 없는 코드들이 결합되어 있기 떄문에 , 하나를 재사용하려고 해도 , 그에 관련된 코드들을 줄줄이 사용하지 않으면 시스템에 문제가 생길 것이다. 또 한 곳에서 동작이 이리저리 퍼지고 , 또 한곳에서 여러동작을 하게 되면 메소드의 이름도 모호해지고 , 하는 일도 명확해지지 않게 될 것이다. 이런 코드를 스파게티 코드 라고 부른다 . 이리저리 서로 얽히고 설켜서 , 끔찍한 코드를 보게 될 것이다 . 이 문제를 해결하기위한 많은 무기들이 있다 . 인터페이..
타입, 추상화 추상화 공통적인 특징들만 모으고 차이점을 배제하는 일반화 , 일반화 되어있는 정보에서 집중하지 않아도 되는 불필요한 정보를 제거해 나감으로서써 단순화를 하여 , 복잡도를 낮추고 좀 더 본래 목적에 집중할수 있게 해주는 작업 예) 지하철 노선도 초기 지하철 노선도는 지도와 일치하는 구체적은 지형까지 담고 있었다. 사실적이지만 목적에서 벗어나는 정보들까지 한번에 너무많은 정보가 들어오다 보니 , 오히려 본래 의도를 전달하기 더욱 어려워 졌다. 지하철 노선도에서 중요한 것은 방향에 따른 역들의 순서를 전달하는 목적에 알맞지 않은 부가적인 정보가 너무 많았다. 훗날 집중해야하는 부분과 집중하지 않아도 되는 부분을 분리해서 제거하여 , 더 본래의 의도에 더욱 맞게 사용할 수 있게 되었다. 객체를 그..