[개발생각] 어플리케이션 레이어에서 UseCase와 Service의 동일시
DDD, 클린아키텍쳐기반으로 설계를 하다보면, UseCase와 Service를 동일시 보고, 하나 개념으로 합치고 싶은 욕망이 들때가 있다. 책이나, 블로그등에 따르면 뭔가 잘못된 생각같고, 찜찜하고 아닌것같은 생각을 하고, 잠시 욕망을 접었던 기억이 많다. 대부분 책에서는 어플리케이션 레이어에서의 UseCase를 '행위의 정의'로 보고, Service는 이런 UseCase들을 이용한 '퍼사드 개념'으로 본다. 그런데, 이론은 그렇다고 해도, 일반적인 서비스에서 저렇게 UseCase와 퍼사드 Service로 나뉘는 경우가 많을까? 의구심이 든다. 그리고 Service를 UseCase의 정의대로 구현하면 (UserGetService, UserLoginService등), 행위의 정의와 퍼사드 개념을 펄쳐서 ..
[개발생각] Test코드 작성시, Fixture의 관리에 대해서
Mock용 객체를 기준값에서 파생되게 만들면, Mock객체의 통일성을 유지할수있고, 서로다른 테스트코드에서도 일관성을 유지하며 테스트코드를 작성할수있다. 테스크 코드를 작성할때, Mock용 User정보, Address정보, Device정보등, 테스트 실행시 필요한 정적인, 준비된 데이트들을Fixture라는 명아래, UserFixture, AddressFixture,DeviceFixture 등의 이름으로 모아두고, 활용하게 된다. 여기서 조금만 관리를 소홀히 하면, Fixture클래스는 온갖 데이터가 난무하는고, 중복 코드가 난무하는 클래스, 즉, 애물단지가 되버린다.여기서 Fixture를 더럽히는 가장 큰 요인하나가, 일관성없는 Mock용 데이터들 정의다. val user1 = User(id=1, na..
[개발생각] 익숙치않은 개발(론)에 팀원들을 적응시키는 방법에 대해서
개발자라면, 같은 회사에서 오랜기간 개발하게 되면, 그 회사만의 방식/방법에 익숙해지게 마련이고, 마치 관습과도 같이 코드를 작성하게 된다.이런게 '콘웨이 법칙'의 예가 아닐까? ㅎㅎ 만약 위와 같은 상황에 지속적으로 노출된다면, 개발자는 점점 관습으로 개발을 하게 되고,(관습이 나쁘다는 이야기는 아니다. 다만, 필연적으로, 개발에 고민하는 시간이 줄어든다는 이야기이다)어느 순간 개발자가 아닌 코더로 전락하게 된다.그런데 정말 무서운것은 코더가 된것을 자신은 모른다는것이다... 정말 무섭다.. 나도 코더였던 경험이 있다. (지금은 당연히 코더가 아니라고 자신있게 말할수있다 ㅎ)대학 졸업후에, 작은 SI개발회사에서 몇년 일하게 됬는데, 어느 순간, 내가 일명 CCCV (컨트롤 C + 컨트롤 V)의 고수가 ..
[개발생각] SOLID원칙에서 I의 경험에 대해서
여러 같은 행위를 하는 Service 빈을 만들어야 할때가 있다. 이경우, 각각의 공통된 행위/과정을 인터페이스 스펙으로 설계하고,그 인터페이스 스펙을 구현하는 AService, BService, CService를 만든다.첫단계에서는 이런 스펙들이 하나의 인터페이스 클래스에 같이 존재하게 되는데,이 스펙들이 많아지고, 성격이 틀리게 되면, 적절하게 그룹핑을 하고, 나눠야 하는 시점이 오게된다. ASpec, BSpec, CSpec등으로 인터페이스 클래스로 나누고, 해당 스펙을 구현하는 구현체를 만든다.구현체는 한개의 클래스에서 모두 구현하는게 아닌, 각각의 스펙별로 별개의 역할을 하는 구현체로 별도로 만드는게 훨씬 깔끔해진다.(일정부분, 단일책임원칙과도 맞는 부분이다) 이 스펙 클래스를 구현한 구현체들은 ..
[개발생각] toString()과 toInt()의 비교 순서에 대해서
작은 차이가 명품을 만든다.. 어느 광고 카피가 생각난다. Int형 userId변수가 있고, string형 userIdStr변수가 존재하는데,이 두개의 값 자체는 정수값으로 같고, 타입만 틀린상태라고 해보자.이 두 변수를 비교해서 처리하는 로직이 아래와 같이 코딩되었다고 가정하면, if (userId.toString() == userIdStr) { //비즈니스 로직} else { //비즈니스 로직}이 코드가 잘 짜여진 코드일까? 생각해보자.. 단연코, 나는 아니라고 생각한다. 엄청 심플한 코드 같지만, 정말 세밀한 차이로 코드의 퀄리티가 달라질수있다.위의 코드는 아쉽지만, 잘못 짜여진 코드라고 생각한다.userIdStr은 String형 타입, 문자열이기에, userIdStr안의 값이 정수값인지, ..
[개발생각] 도메인VO를 컨트롤러의 입력파라미터로 써도될까?에 대한 고민
개발자의 욕심은 끝이 없으니, 재사용, 재사용이라는 프레임에 갇히고, 또 의미를 잃어버리고... 도메인VO를 정의할때, 대부분 그냥 Value Class (코틀린)로 정의해서 사용한다.즉, 대부분은 단순 Wrap 클래스로만 VO를 정의하고 사용한다. 타입 안정성과 명시적 의미부여에 큰 의미를 둘 수 있기에, Wrap 클래스 정도만이여도 상당히 강력하다고 생각하기 때문이다.하지만, 좀더 서비스가 복잡해지고 방대해 진다면, (즉, 다뤄야하는 도메인이 많아진다면)VO가 다양해지고, 해당 VO의 값에 대한 벨리데이션 검증 로직을 VO로 빼는 경우도 많게 된다. 예를 들면Value Class Email(value:String) { init { //value 검증 로직. (Email포멧 검증..
[개발생각] 동일한 역할의 API 인터페이스를 도메인에서 분리해야할때
다른 방식으로 동작하는 동일한 역할을 하는 API는 깔끔하게 도메인 레이어에서 제거하는게 더 깔끔해진다. 도메인 주도 설계 개발을 하게 되면, 아래와 같은 상황이 올때가 있다. 예를 들면, ci를 넘기면, 그 ci의 주민등록상의 주소를 리턴해주는 API를 연동한다고 해보자.그런데, 해당 API는 불안해서, 또는 다른 이유로 같은 기능을 제공하는 몇개의 다른 API를 보조로 사용하려고 한다.(A api 죽으면, B api 사용,)그런데 각각의 A, B API는 응답을 주는 방식이 틀리고, 요청파라미터도 다르다.하나는 요청하면 바로 응답값을 주는 동기방식이고, 하나는 요청하면, 콜백URL을 통해 나중에 전달해주는 콜백 비동기 방식이다. 이런경우, 도메인 서비스에서 비즈니스 로직을 구현할때,해당 api호출을 ..