Design Pattern

    Template Method Pattern

    어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴 - 전체적으로는 동일하면서 부분적으로는 다른 구문으로 구성된 메서드의 코드 중복을 최소화 할 때 유용 - 동일한 기능을 상위 클래스에서 정의하면서 확장/변화가 필요한 부분만 서브 클래스에서 구현 AbstractClass 템플릿 메서드를 정의하는 클래스 하위 클래스에 공통 알고리즘을 정의하고 하위 클래스에서 구현될 기능을 primitive 메서드 또는 hook 메서드로 정의하는 클래스 ConcreteClass 물려받은 primitive 메서드 또는 hook 메서드를 구현하는 클래스 상위 클래스에 구현된 템플릿 메서드의 일반적인 알고리즘에서 하위 클래스에 적합하게 pri..

    정적 팩토리 메서드 패턴

    객체 생성을 캡술화 하는 기법으로 좀더 구체적으로 객체를 생성하는 메서드를 만들고 static으로 선언하는 기법이다. 장점 이름이 있으므로 생성자에 비해 가독성이 좋다. 호출할 때마다 새로운 객체를 생성할 필요가 없다. 하위 자료형 객체를 반환할 수 있다. 객체 생성을 캡슐화할 수 있다. 단점 정적 팩토리 메서드만 있는 클래스라면, 생성자가 없으므로 하위 클래스를 못 만든다. 정적 팩토리 메서드는 다른 정적 메서드와 잘 구분되지 않는다. 위와 같은 장단점이 있는데 하나 씩 확인해보자. 1. 가독성 생성자와 비교했을 때 가독성이 높다는 것인데 비교를 위해서 아래 와 같은 클래스를 만들었습니다. 4개의 정적 팩토리 메서드 패턴을 만들었습니다. public class Character { int STR; in..

    Strategy 전략 프로젝트에 적용 해보기

    문제사항 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class MemberApiControllerTest { ... } 스프링 부트에서 통합 테스를 위해서 위처럼 랜덤한 포트를 배정하게 하면서 내장 redis를 사용하게 되면 여러 스프링 테스트 컨텍스트가 실행되면 EmbeddedRedis가 포트충돌 이를 위해서 레디스를 실행할때 사용가능한 포트를 찾고 이를 레디스에 할당하게 해야 합니다. 여기서 문제는 저의 컴퓨터는 윈도우이고 서버는 리눅스이기 때문에 포트를 찾는 로직이 달라집니다. window public Process executeGrepProcessCommand(int port) throws IOExcept..

    State Pattern

    어떤 행위를 수행할 때 상태에 행위를 수행하도록 위임 시스템의 각 상태를 클래스로 분리해 표현 각 클래스에서 수행하는 행위들을 메서드로 구현 외부로부터 캡슐화하기 위해 인터페이스를 생성하여 시스템의 각 상태를 나타나는 클래스로 실체화 시작과 정지라는 상태로 하는 간단한 예제 1. 상태 인터페이스 public interface State { public void doAction(Context context); } 2. 상태별 구현 클래스 public class StartState implements State{ @Override public void doAction(Context context) { System.out.println("start"); context.setState(this); } @Over..

    Command Pattern

    커맨드 패턴(Command pattern)을 이용하면, 요구사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구사항을 집어넣을 수 도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업취소 기능도 지원이 가능합니다. 커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구 사항을 캡슐화한 것이라는 점을 이미 배웠습니다. 이렇게 하기 위해서 행동과 리시버를 한 객체에 집어넣고, execute()라는 메소드 하나만 외부에 공개하는 방법을 씁니다. 이 메소드 호출에 의해서 리시버에서 일련의 작업이 처리됩니다. 외부에서 볼 때는 어떤 객체가 리시버 역할을 하는지, 그 리시버에서 실제로 어떤 일을 하는지 알 수 없습니다. 그냥 execute() 메소드를 호출하..

    Strategy Pattern

    실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴 특정한 계열의 알고리즘들을 정의하고 각 알고리즘을 캡슐화하며 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 만든다. 이점 컨텍스트 코드의 변경 없이 새로운 전략을 추가할 수 있다는 점입니다. 새로운 정책이 추가될 때 Strategy 인터페이스를 상속받아서 class를 구현하면 됩니다. 기존의 코드를 변경할 필요가 없죠. public interface Strategy { public int doOperation(int num1, int num2); } public class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2)..

    Proxy pattern

    Proxy pattern 프록시 패턴은 어떤 객체에 대한 접근을 제어하는 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴입니다. 일반적으로 프록시는 다른 무언가와 이어지는 인터페이스의 역할을 하는 클래스이다. 프록시는 어떠한 것(이를테면 네트워크 연결, 메모리 안의 커다란 객체, 파일, 또 복제할 수 없거나 수요가 많은 리소스)과도 인터페이스의 역할을 수행할 수 있다. 기본 객체가 리소스 집약적인 경우. 자잘한 작업들은 프록시 객체가 처리하게 한다. 기본 객체에 접근을 제어해야하는 경우. 프록시 객체가 권한에 따라 접근 로직을 다르게 처리하게 한다. 실제로 Spring의 AOP는 Proxy 패턴을 통해서 적용 지점을 지정하고 앞 뒤로 횡단 공통 관심사를 처리하는 하고 있습니다. 프록시 패턴 장점..

    Facade Pattern

    어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공한다. 퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있다. Clent는 Facade 하나만 알고 있으면 수많은 subsystem class들을 사용할 수 있다. 컴퓨터를 작동시키기 위해 우리는 단순히 전원버튼만을 누르지만 이것도 퍼사드 패턴의 예 사용자는 버튼 하나의 클릭 만으로 컴퓨터를 실행 시키지만 컴퓨터 내부에서는 다양한 동작을 통해서 부팅하게 된다. 아래의 예에서는 부팅 과정을 간략화 하였습니다. 1. 서브시스템 클래스 public class CPU { public void freeze() { System.out.println("freeze"); } public void jump() { System..