일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 객체지향프로그래밍
- 의존성
- Solid
- interface
- Swfit
- IOS
- 함수형프로그래밍
- protocol
- 함수형패러다임
- 개발자
- 협업
- 클린소프트웨어
- 인터페이스
- 개발
- 아이폰프로그래밍
- 디자인패턴
- 네이밍
- OOP
- 의도
- SWIFT
- CleanCode
- fp
- 부스트코스
- POP
- 고차함수
- iOS프로그래밍
- 클린코드
- 이름
- DesignPattern
- 문법
- Today
- Total
목록2019/05 (14)
밤에 쓴 코드
객체의 지도 객체를 설계함에 있어서 어떤 고민을 해볼 지 생각해 보자 기능과 구조 지금 부엉이가 친구 병아리를 만나려고 한다. 그래서 병아리는 부엉이에게 자신의 위치를 알려준다. ➡️ 으로 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기능까지 영향을 주어 , 갑자기 엉뚱한 곳이 망가질 수있고 , 그에 따른 연쇄되는 수정이 동반되어야 할것이다. 또 서로 연관 없는 코드들이 결합되어 있기 떄문에 , 하나를 재사용하려고 해도 , 그에 관련된 코드들을 줄줄이 사용하지 않으면 시스템에 문제가 생길 것이다. 또 한 곳에서 동작이 이리저리 퍼지고 , 또 한곳에서 여러동작을 하게 되면 메소드의 이름도 모호해지고 , 하는 일도 명확해지지 않게 될 것이다. 이런 코드를 스파게티 코드 라고 부른다 . 이리저리 서로 얽히고 설켜서 , 끔찍한 코드를 보게 될 것이다 . 이 문제를 해결하기위한 많은 무기들이 있다 . 인터페이..
FP) Currying - 커링 여러개의 인수를 받는 함수를 하나의 인수를 받는 여러 함수로 쪼개는 작업을 커링 이라고 합니다. 커링이 왜 필요할까요 ? ㅡ ? 함수의 꼬리물기(함수의 합성)를 할때 , 특정함수A의 output을 특정함수B의 Input 으로 넣어서 함수가 꼬리에 꼬리를 물어 결과값을 도출하는 프로그래밍을 할 수 있습니다. 이렇게 함수를 합성할 때에 쉽게 함수의 합성을 이루어 내기 위해서는 함수의 인자가 하나이면 함수의 합성이 원활하게 이루어 질수 있습니다. func multifly(_ n1: Int,_ n2: Int) -> Int { return n1*n2 } 인수를 하나만 받는 함수로 줄여보겠습니다. func multifly(_ n1: Int) -> (Int) -> Int { func ..