OOP

    Facade 레이어를 도입해보자

    그동안 과제를 해오면서 다른 데브코스 일원들이 Facade 레이어를 도입하는 것을 보았었지만, 저는 그동안 필요성을 느끼지 못해서 미뤄왔었는데, 이번 프로젝트에서 처음으로 Facade 레이어를 도입해보았습니다. 뮤지컬을 등록하기 위해서 서비스에서 위와 같이 많은 Repository 에 의존성을 갖게 됩니다. 한 메서드 안에서 각 repository 를 사용하는 로직들을 다 수행해줘야 했기에 너무 많은 책임을 갖고 있고, 그에 따라 유지보수도 어렵고 응집성도 떨어지는 코드가 되었습니다. 테스트를 작성할 때도 하나의 메서드 테스트 안에서 너무 방대한 테스트가 될 것 같다는 생각에 구조를 수정해야한다는 필요성을 느끼게 되었습니다. 이렇게 각 Service 들은 각 Repository 하나의 의존성만 갖도록 해..

    템플릿 메서드 패턴

    템플릿 메서드 패턴이란? 💡 특정 작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체적인 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내용을 바꾸는 패턴입니다 우리가 흔히 패턴이라고 인식하지 않고 쓰는 패턴이다. 라면을 끓이는 단계를 템플릿 메서드 패턴의 예시로 들어보겠습니다. public abstract class RamenRecipe { final void prepareRamen() { preparePot() // 냄비 준비 boilWater(); // 물을 끓이기 putBasicMaterial(); // 기본 면, 스프 넣기 if(addMore()) { addIngredient(); // 더 넣고 싶은 것 넣기 } } void preparePot() { System.out.println("냄비..

    추상 팩토리 패턴

    추상팩토리 패턴이란? 💡 서로 관련있는 객체들을 묶어서 팩토리를 만들고, 이 팩토리들을 조건에 따라 생성하도록 다시 팩토리를 만들어서 객체를 생성하는 패턴 예시를 들자면, 컴퓨터를 만들 때, 마우스, 키보드가 필요합니다. 그리고 그 제조사들로 삼성과 lg가 있다고 해봅시다. 하나의 컴퓨터는 당연하게 하나의 제조사로 이루어져야합니다 어제 공부했던 팩토리메서드 패턴을 이용해서 이 상황을 해결해봅시다. 일단 Lg, 삼성 키보드 클래스를 만들고 Keyboard 인터페이스를 정의합니다. 그리고 입력된 조건에 따라 구현체를 만들어주는 KeyboardFactory를 만들어줍니다. public interface Keyboard { } public class SamsungKeyboard implements Keyboar..

    팩토리메서드 패턴

    팩토리 메서드 패턴이란? 💡 부모 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며, 자식 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴 특정 상황에서 조건에 따라서 부모 클래스의 구현체를 다르게 하여 생성해야할 때가 있습니다. 클라이언트에서 조건에 따라 분기하여 생성하면 되겠지만, 클라이언트가 많아진다면 어떨까요? 분기하여 생성하는 로직의 코드가 클라이언트마다 반복되고, 추가적인 분기점이 생긴다면 모든 클라이언트 코드를 수정해야하는 일이 생깁니다. 예시를 한번 들어 보겠습니다. 계산기로 예시를 들어보겠습니다. 최상위 클래스인 TokenType는 계산식을 잘랐을 때 존재할 수 있는 타입의 종류를 의미합니다. TokenType의 구현체에 따라서 하는 일이 다른데, 그래서 클라이언트에서 Toke..

    어뎁터 패턴

    어댑터 패턴이란? 💡 서로 호환되지 않는 인터페이스를 가진 객체들이 상호작용할 수 있도록 두 객체 사이에서 호환을 해주는 구조를 만드는 것입니다. 어댑터 패턴을 어떤 경우에 사용할까? A 인터페이스를 사용하고 싶은데, A 타입의 데이터로만 작동한다. 하지만 나는 B 타입의 데이터를 입력받아 사용해야할 때 → 궁여지책으로 A 인터페이스를 내가 원하는 B타입으로 작동하도록 수정할 수도 있지만, 그렇게 한다면 A 인터페이스에 의존하는 코드들을 수정해줘야한다. 또한, A 쪽의 코드에 내가 접근하지 못하는 경우라면, 이 해결방식조차 이용할 수 없다. 어댑터 패턴을 사용한다면? 클라이언트 코드와 사용하고자하는 코드의 수정 없이 호환 가능한 구조를 만들 수 있다. → OCP 타입을 변환해주는 로직을 분리할 수 있다...