추상클래스 자바에서는 하나 이상의 추상 메소드를 포함하는 클래스를 가리켜 추상 클래스(abstract class)라고 한다. 이러한 추상 클래스는 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메소드의 집합을 정의할 수 있도록 해준다. 추상 클래스는 이를 상속할 각 객체들의 공통점을 찾아 추상화시켜 놓은 것으로, 상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하며 부모 클래스가 가진 기능들을 구현해야 할 경우 사용한다.
인터페이스 인터페이스는 상속 관계를 타고 올라갔을 때 다른 조상 클래스를 상속하더라도, 같은 기능이 필요할 경우 사용한다.
제네릭이란 JDK 1.5부터 도입한 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법이다. 제네릭이 갖는 의미는 ‘일반화’이다. 그리고 자바에서 그 일반화의 대상은 자료형이다.
용어 Box<T> 클래스에서 사용된 T를 가리켜 ‘타입 매개변수(Type Parameter)’라 한다. 메소드의 매개변수와 유사하게 자료형 정보를 인자로 전달받는 형태이기 때문이다. <>안에 전달되는 것을 가리켜 ‘타입 인자(Type Argument)’라 한다. 타입 매개변수 T에 전달되는 인자로 바라보고 그렇게 이름을 지어준 것이다. Box<Apple> aBox = new Box<Apple>(); -> Box<Apple>을 가리켜 ‘매개변수화 타입(Parameterized Type)’이라 한다.
포워드 프록시(Forward Proxy) 일반적으로, 프록시 서버라고 하면 포워드 프록시를 의미한다. 포워드 프록시란 클라이언트와 인터넷 사이에 프록시가 위치해서 클라이언트 대신 서버에 요청을 보내주는 형태를 말한다.
포워드프록시를 통해 얻는 이점은 다음과 같다.
로컬 네트워크와 인터넷 사이 오가는 트래픽을 제어할 수 있다. 예를 들어 초등학교 안에서 학생들이 부적절한 콘텐츠를 브라우징하는 것을 막기 위해서 포워드 프록시를 사용할 수 있다. 포워드 프록시는 대개 캐싱 기능이 있으므로 어떤 콘텐츠가 빈번하게 사용된다면 월등한 성능 향상을 가져올 수 있다.
DIP(Dependency Inversion Principle) 우리가 다루는 모듈은 고수준 모듈과 저수준 모듈로 나눌 수 있다. 고수준 모듈이란 의미있는 단일 기능을 제공하는 모듈이며, 저수준 모듈은 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현인 모듈이다. Layered Architecture 상에서 Application 및 Domain 등의 고수준 모듈은 Infrastructure라는 저수준 모듈을 의존한다. 그 결과, 구현 부분의 변경에 유연하지 못하고 테스트하기 어렵다는 문제점이 발생한다.
DIP(Dependency Inversion Principle)이란 의존 관계를 역전시켜서 저수준 모듈이 고수준 모듈에 의존하도록 구현하는 것을 의미한다.
디미터의 법칙(Law of Demeter) 디미터의 법칙은 “Object-Oriented Programming: An Objective Sense of Style” 에서 처음으로 소개되었다. Demeter라는 프로젝트를 진행하던 개발자들은 어떤 객체가 다른 객체에 대해 지나치게 많이 알다보니, 결합도가 높아지고 좋지 못한 설계를 야기한다는 것을 발견하였다. 그래서 이를 개선하고자 객체에게 자료를 숨기는 대신 함수를 공개하도록 하였는데, 이것이 바로 디미터의 법칙이다.
즉, 디미터의 법칙은 다른 객체가 어떠한 자료를 갖고 있는지 속사정을 몰라야 한다는 것을 의미하며, 이러한 이유로 Don’t Talk to Strangers(낯선 이에게 말하지 마라) 또는 Principle of least knowledge(최소 지식 원칙) 으로도 알려져 있다.
객체지향과 캡슐화 객체는 캡슐화된 상태와 외부에 노출되어 있는 행동을 갖고 있으며, 다른 객체와 메시지를 주고 받으면서 협력한다. 객체는 메시지를 받으면 객체 그에 따른 로직(행동)을 수행하게 되고, 필요하다면 객체 스스로 내부의 상태값도 변경한다. 간단히 말해서 객체지향 프로그래밍은 객체가 스스로 일을 하도록 하는 프로그래밍이다.
상태를 가지는 객체를 추가했다면 객체가 제대로 된 역할을 하도록 구현해야 한다. 즉 객체가 로직을 구현하도록 한다. 상태 데이터를 꺼내 로직을 처리하도록 구현하지 말고 객체에 메시지를 보내 일을 하도록 해야한다.