Dependency Inversion Principle

DIP(Dependency Inversion Principle) 우리가 다루는 모듈은 고수준 모듈과 저수준 모듈로 나눌 수 있다. 고수준 모듈이란 의미있는 단일 기능을 제공하는 모듈이며, 저수준 모듈은 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현인 모듈이다. Layered Architecture 상에서 Application 및 Domain 등의 고수준 모듈은 Infrastructure라는 저수준 모듈을 의존한다. 그 결과, 구현 부분의 변경에 유연하지 못하고 테스트하기 어렵다는 문제점이 발생한다. DIP(Dependency Inversion Principle)이란 의존 관계를 역전시켜서 저수준 모듈이 고수준 모듈에 의존하도록 구현하는 것을 의미한다.

디미터의 법칙(Law of Demeter)

디미터의 법칙(Law of Demeter) 디미터의 법칙은 “Object-Oriented Programming: An Objective Sense of Style” 에서 처음으로 소개되었다. Demeter라는 프로젝트를 진행하던 개발자들은 어떤 객체가 다른 객체에 대해 지나치게 많이 알다보니, 결합도가 높아지고 좋지 못한 설계를 야기한다는 것을 발견하였다. 그래서 이를 개선하고자 객체에게 자료를 숨기는 대신 함수를 공개하도록 하였는데, 이것이 바로 디미터의 법칙이다. 즉, 디미터의 법칙은 다른 객체가 어떠한 자료를 갖고 있는지 속사정을 몰라야 한다는 것을 의미하며, 이러한 이유로 Don’t Talk to Strangers(낯선 이에게 말하지 마라) 또는 Principle of least knowledge(최소 지식 원칙) 으로도 알려져 있다.

캡슐화

객체지향과 캡슐화 객체는 캡슐화된 상태와 외부에 노출되어 있는 행동을 갖고 있으며, 다른 객체와 메시지를 주고 받으면서 협력한다. 객체는 메시지를 받으면 객체 그에 따른 로직(행동)을 수행하게 되고, 필요하다면 객체 스스로 내부의 상태값도 변경한다. 간단히 말해서 객체지향 프로그래밍은 객체가 스스로 일을 하도록 하는 프로그래밍이다. 상태를 가지는 객체를 추가했다면 객체가 제대로 된 역할을 하도록 구현해야 한다. 즉 객체가 로직을 구현하도록 한다. 상태 데이터를 꺼내 로직을 처리하도록 구현하지 말고 객체에 메시지를 보내 일을 하도록 해야한다.

자바의 Proxy 구현

Pure Java, JDK Dynamic Proxy, CGLib Dynamic Proxy를 이용하여 문자열을 대문자로 변환하는 프록시를 구현해보도록 하자. 인터페이스와 타겟 클래스는 다음과 같다. 1 2 3 4 5 public interface Hello { String sayHello(String name); String sayHi(String name); String sayThankyou(String name); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class HelloTarget implements Hello { @Override public String sayHello(String name) { return "Hello " + name; } @Override public String sayHi(String name) { return "Hi " + name; } @Override public String sayThankyou(String name) { return "Thankyou " + name; } } 예상 결과는 다음과 같다.

DTO vs VO

DTO Data Transfer Object의 약자로 계층(Layer) 간 데이터를 전달하는 객체이다. 조금 더 쉽게 말하면, 데이터를 담아서 전달하는 바구니라고 할 수 있다. Controller는 View와 도메인 Model의 데이터를 주고 받을 때 별도의 DTO 를 주로 사용한다. 도메인 객체를 View에 직접 전달할 수 있지만, 민감한 도메인 비즈니스 기능이 노출될 수 있으며 Model과 View 사이에 의존성이 생기기 때문이다. DTO는 데이터 접근 메서드(Getter, Setter), 생성자 외에 기능을 갖지 않는다. (정렬, 직렬화 등 데이터 표현을 위한 기능은 가질 수 있다.

volatile

volatile란? volatile 키워드는 java 변수를 Main Memory에 저장하겠다라는 것을 명시한다. 즉 매번 변수의 값을 읽을 때마다 CPU cache에 저장된 값이 아닌 Main Memory에서 읽는 것이다. 또한 변수의 값을 쓸 때마다 Main Memory까지 작성한다. volatile 키워드의 필요성 멀티쓰레드 어플리케이션에서의 non-volatile 변수에 대한 작업은 성능상의 이유로 CPU 캐시를 이용한다. 둘 이상의 CPU가 탑재된 컴퓨터에서 어플리케이션을 실행한다면, 각 쓰레드는 변수를 각 CPU의 캐시로 복사하여 읽어들인다. 쓰레드가 변경한 값이 메인 메모리에 저장되지 않아서 다른 쓰레드가 이 값을 볼 수 없는 상황을 ‘가시성’ 문제라 한다.