10월 22일 @zoom
깃허브 레포지토리
수형님 코드(@suhshin)
코드리뷰
•
네이밍 컨벤션 잘했다
◦
스위프트 문서에 들어오면 네이밍파트에 네이밍을 어떻게 할것이냐에 대한 가이드가 있는데 여기를 꼭 참여해서 하면 좋을거같다
◦
코드 네이밍이 잘 되어있으면, 주석이 필요 없다
◦
swift api design guide 보고 네이밍 참고하기!
◦
swift language guide 에 있는 코드 조각들에 코딩 컨벤션이 잘 나와있다.
◦
연습이더라도 실전처럼 컨벤션, 네이밍 잘 지켜라!
•
데이터소스 클래스(MatchListDataSource)를 분리했었던게 매우 인상적
◦
이게 모델로도 취급, 컨트롤러로도 취급, 되는데 왜 이렇게 했나?
◦
S. 찾아보니까 델리게이트 패턴을 활용해서 하는게 있길래 적용해봤다.
◦
이거는 매우 좋은 시도였다. 데이터소스를 타입으로 분리한건 매우 좋다. 데이터소스라는 컨트롤러가 하나더 생긴느낌..?
•
질의 응답
Q. 네트워크를 집어넣으면, 데이터가 유실될수도있지 않을까?
페이지가 넘어간 부분에서 복사된 데이터를 가지고 있을때, 앱이 강제종료 된다는 상황이 발생한다면, 이런부분 처리를 어떻게 해야하나......
데이터 저장 타이밍은 기획에서 정한다
Q. 만약 optional자료형을 써야할 때, 지금 코드에서는 forced unwrapping을 사용하였는데 너무 많이 사용하다보니 안좋은 것 같다. 해결책이 있을까
우선 옵셔널 "?" 는 필요없어도 되는 데이터에 대해서 사용한다. 만약 정말로 필요한 데이터라면 암시적 추출 옵션인 "!" 를 사용해야한다. 없어서는 안된다는걸 강력히 주장해야된다.
그리고 만약 암시적 추출 옵션을 사용하는 코드가 생긴다면, 항상 해당 스코프 내에서 바인딩을 해주는 것이 좋다.
추가. 만약 guard let 구문에서 nil 체크만 하고싶다면, 아래와 같은 코드가 가독성이 좋다.
아래 코드는 기존코드
// 이렇게 사용하는 것은 가독성 측면에서 좋지 않다.
guard opponent != nil else {
fatalError("opponent is nil")
}
Swift
복사
규호님 코드(@kyuhkim)
•
네이밍 하려고 신경 쓴건 보이나, 좀더 신경 써보자
•
SpriteKit
◦
스프라이트 킷을 사용하였는데 왜?
▪
K. 게임이라서 게임을 선택했더니 이게 되었다. 대부분 기본 코드가 되어있는거 그대로 썼다. 그 코드보고 적당히 해봤는데 뷰랑 컨트롤이랑 제대로 한게 맞는지..?
▪
View 의 label 을 그냥 컨트롤러로 옮겨서 사용했다.
◦
뷰와 컨트롤러가 서로 바라볼 필요는 없다. 그냥 컨트롤러가 뷰만 알고있으면 된다.
◦
뷰가 컨트롤러를 가지고있는 이유는?
▪
터치했을떄, 뷰가 컨트롤러로 전달하고 싶어서
◦
뷰가 컨트롤러를 다 들고있을필요는 없고, 이벤트 전달 용으로 델리게이트를 쓰면 된다.
•
모델이 수정되면, 수정됐다고 컨트롤러한테 말해줄필요없고, 그냥 옵저빙으로 되는거니까 잘했다. 모델안에서 모델이 값이 바꼈다는걸 알려주고싶으면 notification center를 쓰거나, delegate 패턴을 활용하는것도 나쁘지 않다.
•
네트워크 관련
◦
K. 네트워크 decode 하는걸 어디서 하는게 맞나요 네트워킹? 모델?
◦
통상적으로 어디에 있는게 좋다 이런건 없고, 조직에 따라서 명확하게 결정만 하면 된다. alamofire 네트워킹 라이브러리에서 어떻게 구현하는지 확인해보면 좋다.
네트워크 라고 하더라도, 그 목적에 맞게 다 나눠서 쓰고있긴하다. 또 큐모에 따라서 리펙토링 하면서 책임과 역할을 또 나뉠수 있으니까,
◦
명확한 이유가 있고 그렇게 하기로 했다면 괜찮다.
의민님 코드(@echung)
•
아직 C 언어 코드 있다
•
MVC 잘했나요?
◦
모델쪽에서 코드 재사용이 불리하다
◦
플레이어가 2명이라는게 전제하에 고정되어있다. 게임 참가자가 1명 더 늘어나면 코드 재사용이 불가능하다
◦
야곰이라면
▪
참가자마다 점수를 기록할 모델(플레이어의 상태를 갖는)을 만든다.
•
"캡슐화"
◦
외부에서 직접 접근 못하게 프로퍼티 private으로, 대신 다른 방식으로 접근할 수 있도록
•
모델은 소지해야할 값을 가지고있거나, 수정하거나
◦
외부에서 함부로 수정하게 하면 안된다.
◦
값을 숨겨놓고 메서드를 통해서 가져온다
•
점수 비교는 컨트롤러에서
•
주사위 게임의 규칙이 바뀔수있다라는걸 가정해놓고 해야된다.
◦
하드코딩된 부분은 웬만하면 의존성 주입 쓸것
◦
기본값을 쓰지말고, 의존성 주입으로 기본값을 받아올것
◦
외부에서 값들을 주입 하면서 초기화하게 되면 훨씬 유연해진다.
▪
구현 코드를 건드는것은 매우 위험하니까, 써야한다
▪
예)
•
시간당 3천원 주차장 → 시간당 5천원 주차장이 되버린다면, 핵심값이 바뀐거라서 오류가 남
•
들어오고 나갈때 가격을 확인하게 설계되어있으면 오류 안남...
◦
매직넘버같은 하드코딩을 줄이도록 할것!
◦
전역변수로 둬도 괜찮다
의민 코드 리팩토링 중 struct 대신 class로 쓴 이유
•
참조를 할 일이 많을거같아서 클래스로 했다.
•
여기저기서 값을 복사해서 들고가는것보다,
•
여기저기서 참조가 되어야한다면 클래스를 사용할것같다
Struct vs. Class
MVC
•
MVC 를 제대로 구현하였는가?
◦
모델과 뷰는 독립적이어야 함
▪
모델을 제거해도, 뷰에는 영향이 없는가
▪
뷰를 제거해도, 모델에는 영향이 없는가
•
뷰는 컨트롤러한테 이벤트만 전달하는 코드
◦
어차피 뷰 클래스를 따로 만들지 않고, 주어지는거 썼으니까 갠춘
◦
모델 지워도 뷰가 잘 돌아가니까 지금 코드는 괜춘
•
MVC 에서 컨트롤러는 중간에 여러개가 될수도있다 ㄷ ㄷ
◦
컨트롤러가 하나만 하면 엄청 커진다. ㄷㄷ
◦
수형님 코드에서 데이터소스 분리한거 잘했음.
Unit test
•
모델이랑 컨트롤러가 잘 되어있으면,
◦
실제 UI 없이, unit test 를 진행 해 볼 수 있다.
◦
Unit test Bundle
◦
Setup, tearDOwn 등등 자세한건 야곰닷넷에 unit test 강좌가 있다. → 무료
◦
테스트는 test 로 이름이 시작되어야한다.
◦
XCTAssert(1 < 2 ) 같은걸 하고, 옆에 테스트 버튼을 누르면 테스트가 된다.
◦
테스트는 보기 편할수록 좋으니까 그냥 한글로 하기도 한다.
◦
단축키 CMD + U
◦
코드 작성할 때, 역할과 책임을 분리하고, (UML 로 타입들의 관계와 역할을 나타내고) 코드를 작성하면서 테스트도 같이 작성한다
◦
TDD 프로젝트 진행방식
▪
Test Driven Development