Sangil's blog

https://github.com/ChoiSangIl Admin

[좋은코드, 나쁜코드] 2장 추상화 계층 DEV / PROGRAMING

2023-05-22 posted by sang12


https://github.com/ChoiSangIl/book/blob/main/%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C,%20%EB%82%98%EC%81%9C%EC%BD%94%EB%93%9C/2%EC%9E%A5%20%EC%B6%94%EC%83%81%ED%99%94%20%EA%B3%84%EC%B8%B5.md

코드 작성의 목적은 문제 해결이다.

"결국 코드 작성의 목적은 문제 해결이다. 어떻게 하면 효율적으로 문제를 해결할 수 있는지?
추상화 계층을 통해 설명하려고 하는거 같다. 결국 가독성과 재사용성을 위한게 아닐까"

추상화 계층 및 코드 품질의 핵심 요소

  • 가독성

  • 모듈화

  • 재사용성 및 일반화성

  • 테스트 용이성

"당연한 말... 추상화 하면 좋은점"

API 및 구현 세부사항

어떤 코드를 호출하는 쪽에서 그 코드에 대해 알고 있는 사항을 공개 API라고 생각할 수 있다.
API로 공개되지 않은 내용은 구현 세부사항이다

"결국 공개할 API 는 인터페이스화 시켜 공개하고 구현체에 세부사항을 위임한다.
당연하게도 테스트하기 쉬워지며, 추상화의 이점을 얻어 코드는 이해하기 쉬워진다. 이것또한 당연한 말..."

모든 것을 위한 인터페이스?

  • 장점

    • 퍼블릭 API를 매우 명확하게 보여준다

    • 테스트를 쉽게할 수 있다

    • 쉽게 갈아낄 수 있다. -> 오늘 확신한 것과 한달 후에 확신한 것이 다를 수 있다.

      • 같은 클래스로 두 가지 하위 문제를 해결할 수 있다.

  • 단점

    • 더 많은 작업이 필요하다 (보일러코드)

    • 코드가 복잡해질 수 있다

      • 실제 구현을 파악할 때 구현체를 구현하는 구체클래스를 찾아야 한다.

층이 너무 얇아질 때

= 너무 많은 클래스로 나눴거나, 모든 것을 인터페이스로 만들엇다면..

  • 보일러 코드가 늘어난다

  • 로직을 이해하려면 많은 파일이나 클래스를 따라가야 한다.

  • 인터페이스 뒤에 숨은 구현체들을 파악하기 힘들다 (로직을 이해하거나 디버깅하는 것이 어렵다)

코드를 서로 다른 계층으로 분할해서 얻는 장점과 비교하면 이러한 비용은 상당히 낮은 것이지만 분할을 위한 분할은 의미가 없다는 것을 명심해야 한다.
비용이 이익보다 더 큰 시점이 올 수 있으므로 상식에 맞게 적용하는 것이 좋다.
너무 비대한 계층 때문에 발생하는 문제는 너무 얇은 계층 때문에 발생하는 문제보다 더 심각하다.
확실하지 않은 경우 남용의 위험에도 불구하고 계층을 얇게 만드는 것이 좋다.

"확실하지 않을때면 무조건 계층을 얇게 만들는 것이 좋다? 동의되지 않는다. 결국 그때그때 마다 다르니 잘써라는 말로 들리는건... 기분 탓"

클래스

'클래스는 응집력이 있어야 하고 한가지 일에만 관심을 가져야 한다'와 같은 말에 동의하지 않는 개발자들은 만나보지 못했다.
하지만 이 조언을 알고 있음에도 불구하고 많은 개발자가 여전히 너무 큰 클래스를 작성한다.

느낀점

복잡한 하나의 코드 예시를 제시하고 이를 함수 및 클래스로 분리 하며 최종적으로 인터페이스를 통해 추상화 하며 장점들을 설명한다. 2장에서도 당연한 말들로 시작해 당연한 말로 끝이난다.

  • 하지만 해당 내용을 알고 있음에도 개발자는 여전히 너무 큰 클래스를 작성한다… 이게 2장에서 제일 중요한 말이 아니 였을까?

REPLY

DDD Domain Service와 Application Serivce의 차이가 뭘까? DEV / WEB

2023-03-11 posted by sang12


도메인 주도 설계 5장 Service (에릭에반스)

책에서 나온 예시

계좌 잔고가 일정 금액 아래로 떨어지면 고객에게 이메일을 발송하는 에플리케이션이 있다.
-> 계좌이체를 해서 잔고가 일정 금액이상 떨어지면 이메일을 발송하는것을 말하는듯…

응용 계층 ( Application Service ) 의 책임

  • 자금 이체 응용 서비스

    • 입력 내용의 암호화

    • 이체 처리를 위한 도메인 서비스로의 메시지 전송

    • 이체 확인 대기

    • 인프라스트럭처 서비스를 이용한 통지 결정

도메인 서비스의 책임

  • 자금 이체 도메인 서비스

    • 금액 인출/입금에 필요한 Account(계좌)와 Ledger(원장) 객체 간의 상호작용

    • 이체 결과 확인 정보 제공(이체 수락 여부 등)

인프라 스트럭처

  • 통지 서비스

    • 애플리케이션에서 지정한 곳으로 이메일이나 우편 등을 보냄

여기서 도메인 서비스가 왜 필요할까?

도메인 개념 가운데 객체로는 모델에 어울리지 않는 것이 있다. 필요한 도메인 기능을 Entity나 Value에서 억지로 맡게 하면 모델에 기반을 둔 객체의 정의가 왜곡되거나, 또는 무의미하고 인위적으로 만들어진 객체가 추가될 것이다.

위의 예시에서 보면 도메인 서비스에서는 Account(계좌)와 Ledger(원장) 객체에 접근을 해야 자금 이체를 할 수 있다. 결국 도메인 객체 안에서 혼자 해결될 수 없는데 도메인과 연관된 서비스의 경우 도메인 서비스에 설계가 되야 한다. 예제에서는 입력 내용을 암호화 하거나 메세지를 전송하는 것은 도메인 업무 규칙과는 상관이 없다.

도메인 서비스의 특징

  • 연산이 원래부터 Entity나 Value Object의 일부를 구성하는 것이 아니라 도메인 개념과 관련돼 있다.
    -> 해석….ㅠㅠ 도메인으로 처리할 수 없지만 도메인 개념과 관련되 있다는 이야기 인듯..?

  • 인터페이스가 도메인 모델의 외적 요소의 측면에서 정의된다.
    -> 해석….ㅠㅠ 요것도 도메인 모델에서 처리할 수 없다는 말인 거 같다.

  • 연산이 상태를 갖지 않는다

도메인 서비스를 사용하면 뭐가 좋을까?

세밀한 도메인 객체 (세밀한 도메인 객체가 뭔가요 대체)에서 지식이 새어 나오게 해서 도메인 객체의 행위를 조정하는 응용 계층을 흘러가게 할 수 있다.

→ 응용 계층(Application Service)에 도메인 규칙들이 스며드는 것을 말하는 듯

도메인 서비스를 적절히 도입하면 계층 간의 경계를 선명하게 하는 데 도움될 수 있다.

→ 응용 계층에 도메인 규칙들이 스며드는 것을 막을 수 있어서 계층 간의 경계를 더욱 선명하게 하는데 도움이 될 수 있다.

REPLY

[좋은코드, 나쁜코드] 1장 코드는 어떻게 소프트웨어가 되는가 DEV / PROGRAMING

2023-05-22 posted by sang12


코드 품질의 목표

  1. 작동해야 한다

  2. 작동이 멈춰서는 안된다

  3. 변화하는 요구 사항에 적응해야 한다

  4. 이미 존재하는 기능을 또 다시 구현해서는 안 된다.

"너무 뻔한말이 아닌가..?"

코드는 작동해야 한다

"너무 당연해서 패스"

코드는 작동히 멈추면 안 된다

코드의 작동은 매우 일시적일 수 있다. 왜?

  • 다른 코드에 의존할 수 있는데, 그 코드가 수정되고 변경될 수 있음

  • 새로운 기능이 필요할 때 코드를 수정해야 할 수도 있음

  • 해결 하려고 하는 문제는 시간이 지남에 따라 변경된다. 소비자 선호, 비즈니스 요구, 고려해야 할 기술 등이 바뀔 수 있다.

"여기에서도 의존이라는 말이 나오는구나"

코드는 변경된 요구사항에 적응할 수 있어야 한다.

한 번 작성하고 다시는 수정되지 않는 코드는 거의 없다
왜?

  • 비즈니스 환경이 변한다.

  • 사용자 선호가 변한다

  • 가정이 더 이상 유효하지 않다.

  • 새로운 기능이 계속 추가된다.

적응 가능한 코드를 작성하기 위해 얼마나 많은 노력을 기울여야 할지에 대해 균형 잡힌 결정을 내리는 것은 까다롭다.

"정말 해당 기능이 자주 사용 될것이고 핵심 기능이기 때문에 이정도의 노력을 들여서 개발해야지 라는 결정을 내리는 것은 어려운 것 같다."

"2가지 극단적인 예로 설명하지만 정말 극단적인거 같다."

결국에는 적응성 높은 코드를 작성 해야 된다라는 말

코드는 이미 존재하는 기능을 중복 구현해서는 안 된다

  • 이미 구현한 코드를 재사용하면 좋은 점

    • 시간과 노력을 절약한다

    • 버그 가능성을 줄여준다

    • 기존 전문지식을 활용한다

    • 코드가 이해하기 쉽다

"당연한 말.."

코드 품질의 핵심 요소

  • 코드는 읽기 쉬워야 한다.

  • 코드는 예측 가능해야 한다.

  • 코드를 오용하기 어렵게 만들라.

  • 코드를 모듈화하라.

  • 코드를 재사용 가능하고 일반화할 수 있게 작성하라.

  • 테스트가 용이한 코드를 작성하고, 제대로 테스트하라.

"이건 당연한 말이지만 실제로 실천하기에는 많은 노력이 필요한거 같다."

코드는 읽기 쉬워야 한다.

형편 없이 짜여진 코드를 읽고 무엇에 대한 것인지 알아내려고 노력하는 것은 방금 전 브라우니 레시피(가독성이 낮은 글)를 읽는 경험과 다르지 않다.

우리는 코드를 읽을 때 다음 사항을 이해하기 위해 애쓴다.

  • 코드가 하는 일

  • 어떻게 그 일을 수행하는지

  • (입력이나 상태 등) 어떤 것을 필요로 하는지

  • 코드 실행 결과물

코드의 가독성이 떨어진다면, 다른 개발자가 그 코드를 이해하는 데 많은 시간으 들여야 한다. 또한 코드의 기능을 잘못 이해하거나 중요한 세부사항을 놓칠 가능성 역시 크다.

"가독성이 최고시다"
결국 가독성이 낮으면 코드 검토 중에 버그를 발견할 가능성이 작고, 다른 사람이 수정하면서 버그가 도입될 가능성이 크다.

소프트웨어가 수행하는 모든 일은 그것을 가능하게 하는 어떤 코드에 의해 일어난다!

코드는 예측 가능해야 한다

코드가 아무리 좋은 의도를 가지고 있더라도 예상을 벗어난 동작을 수행하는 것은 위험할 수 있다.
이런 코드는 사소한 오류를 일으킬 수도 있지만, 어떤 경우에는 중요한 데이터가 손상되는 재앙과도 같은 상황을 초래할 수도 있다.
"이것도 당연한 말..."

코드를 오용하기 어렵게 만들라

TV 뒷면을 보면 전원 어댑터와 HDMI 어댑터가 있다.
그런데 TV 제조사에서 이를 다 동일하게 만들면?? HDMI 에 전원 을 꽂았다가 TV가 폭발할 수도 있다.
자신의 코드를 작성할 때 다른 코드가 어떤 것을 꽂기를 기대한다. 즉 호출할 때 인수가 입력되거나 시스템이 특정 상태에 있을 것을 예상한다.
자신이 작성한 코드에 잘못된 것들이 꽂히면, 모든것이 폭발할 수 있다.
"예시가 재밌네"

코드를 모듈화하라

모듈화 되어 있는 코드가 수정하기 쉽다

코드를 재사용 가능하고 일반화할 수 있게 작성하라

테스트가 용이한 코드를 작성하고 제대로 테스트하라.

  • 사람은 실수를 하는 존재다

고품질 코드 작성은 일정을 지연 시키는가?

코드 품질을 고려하지 않고 떠오르는 대로 코딩하면 처음에는 시간을 절약할 수 있다. 그러나 머지 않아 취약하고 복잡한 코드베이스로 귀결될 것이며, 점점 이해하기 어렵고 추론할 수 없는 코드가 된다.
"서두르지 않으면 더 빠르다"

느낀점

"저자는 코드 품질의 핵심 요소에 대해 설명하고 있다. 어찌보면 당연한 이야기로 보이는 말들이 많은데 개발하다보면 이런 기본적인 것들을 생각하지 못할때가 종종 있는거 같다. 다시 한번 생각하고 가자!"

REPLY