
Head First Design Patterns 8. Template Method Pattern
2022. 2. 27. 22:22
Design Patterns
템플릿 메소드 패턴(Template Method Pattern) 예제 code reference 템플릿 메소드(Template Method)에서는 알고리즘의 각 단계들을 정의하며, 그 중 한 개 이상의 단계가 서브클래스에 의해 제공될 수 있습니다. 아래 예시를 살펴보면 CaffeineBeverage 클래스에서 알고리즘을 독점하고 있는 것(prepareRecipe)을 볼 수 있습니다. 그리고 이 알고리즘의 일부 구현만 서브 클래스에 의존합니다. 그래서 알고리즘은 한 군데에 있기 때문에 그 부분만 고치면 됩니다. CaffeineBeverage.java public abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); brew(..

Head First Design Patterns 7. Facade Pattern
2022. 2. 26. 09:37
Design Patterns
퍼사드 패턴(Facade Pattern)의 정의 퍼사드 패턴(Facade Pattern)은 하나 이상의 복잡한 인터페이스를 깔끔하면서도 말쑥한 퍼사드(겉모양, 외관 등을 뜻함)으로 덮어주는 패턴입니다. 일련의 복잡한 클래스들을 단순화하고 통합된 클래스를 제공합니다. Head First Design Patterns에서는 아래와 같이 퍼사드 패턴을 정의합니다. 퍼사드 패턴(Facade Pattern) 어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공합니다. 퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있습니다. 최소 지식 원칙 Design Pattern 7. 최소 지식 원칙 - 정말 친한 친구하고만 얘기하라. 시스템을 디자인 할 때, 어떤 객체든 그 객체와..

Head First Design Patterns 6. Command Pattern
2022. 2. 25. 23:02
Design Patterns
커맨드 패턴(Command Pattern) 예시 커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구 사항을 캡슐화합니다. 아래 샘플 코드에서 SimpleRemoteControl 은 인보커(Invoker) 클래스, LightOnCommnad 클래스는 커맨드(Command) 클래스, Light 는 리시버(Receiver) 클래스, RemoteControlTest 는 클라이언트(Client) 클래스의 예시입니다. reference code SimpleRemoteControl.java (Invoker) SimpleRemoteControl 은 Command 객체를 들고 있습니다. 그리고 실제 Command 객체가 어떤 객체인지, 어떤 일을 하는지 상관없이 버튼이 눌리면 execute 함수를 호출합니다..

Head First Design Patterns 5. Singleton Pattern
2022. 2. 20. 23:18
Design Patterns
싱글톤 패턴(Singleton Pattern)의 용도 스레드 풀, 캐시, 대화상자, 사용자 설정 혹은 레지스트리를 처리하는 객체, 로그 기록용 객체, 디바이스 드라이버 등 객체 중에 하나만 있으면 되는 경우 사용합니다. 고전적인 싱글톤 패턴(Singleton Pattern) 고전적인 싱글톤 패턴 방식은 아래와 같습니다. 생성자는 private 으로 설정하고, 객체를 부를 때에는 따로 static 함수를 사용합니다. 인스턴스가 있을 경우에는 그대로 그 인스턴스를 반환하고, 인스턴스가 없을 경우에는 생성하여 인스턴스를 반환하변 됩니다. public class Singleton { private static Singleton uniqueInstance; private Singleton() {} public s..

Head First Design Patterns 4. Factory Pattern
2022. 2. 19. 23:00
Design Patterns
흔히 말하는 팩토리 패턴(Factory Pattern)에는 팩토리 메소드 패턴(Factory Method Pattern)과 추상 팩토리 패턴(Abstract Factory Pattern) 두 가지 패턴이 있습니다. 이 패턴들에 대해 오늘 순서대로 알아보겠습니다. 팩토리 패턴(Factory Pattern)의 필요성 new를 사용하는 것은 구상 클래스의 인스턴스를 만드는 것입니다. 구상 클래스를 바탕으로 코딩을 하면 나중에 코드를 수정해야할 가능성이 높아지고, 유연성이 떨어지게 됩니다. 그 예가 아래와 같습니다. code reference 구상 클래스를 사용하면 아래처럼 조건에 따라 만들려고 하는 구상 클래스를 명시해줘야 합니다. 이는 뭔가 변경하거나 확장해야할 때 코드를 또 확인하고 추가해야한다는 뜻이죠...

Head First Design Patterns 3. Decorator Pattern
2022. 2. 13. 23:07
Design Patterns
OCP(Open-Closed Principal) Design Principal 5. 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다. 기존 코드는 건드리지 않은 채로 확장을 통해서 새로운 행동을 간단하게 추가할 수 있게 구조를 잡으면 새로운 기능을 아주 유연하게 추가할 수 있으면서도 강하고 견고한 디자인을 만들 수 있습니다. 다만, 무조건 OCP를 적용하는 것은 시간 낭비가 될 수도 있고, 쓸 데 없는 일일 수 있으니 유의하여야 합니다. 데코레이터 패턴(Decorator Pattern)의 정의 데코레이터 패턴은 객체를 다른 객체로 "장식"하는 것입니다. 데코레이터 패턴은 아래와 같이 정의됩니다. 데코레이터 패턴에서는 객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터..

Head First Design Patterns 2. Observer Pattern
2022. 2. 6. 23:52
Design Patterns
옵저버 패턴(Observer Pattern) 동작 방식 옵저버 패턴(Observer Pattern)에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의합니다. code reference 주제 객체에 옵저버를 옵저버 목록에 추가합니다. 주제 객체의 값이 바뀌면 등록된 옵저버들에게 연락을 합니다. 데이터를 받을 필요가 없는 옵저버들은 옵저버 목록에서 삭제합니다. 느슨한 결합(Loose coupling)의 위력 옵저버 패턴에서는 주제와 옵저버가 느슨하게 결합되어 있는 객체 디자인을 제공합니다. 주제가 옵저버에 대해서 아는 것은 옵저버가 특정 인터페이스를(Observer Interface)를 구현한다는 것 ..

Head First Design Patterns 1. Strategy Pattern
2022. 2. 5. 23:31
Design Patterns
패턴 관련 코드는 아래 링크를 통해 확인 가능합니다. sample source code 상속만 사용했을 경우의 단점 상속을 사용하면 코드를 재사용할 수 있지만, 실제 코드를 정비를 하는 데에는 어려움이 있을 수 있습니다. 예를 들어, 자식 클래스에서 부모 클래스와 다른 방식으로 method 로직을 수행해야 한다면 상속을 굳이 사용할 필요가 있을까요? code reference 소프트웨어를 만들 때, 나중에 혹시 고쳐야 할 때도 기존 코드에 미치는 영향은 최소한으로 만들면서 작업할 수 있도록 설계를 해야합니다. 그래서 상속을 사용할 때와 인터페이스를 사용할 때를 적절하게 구분할 수 있어야 합니다. Design Principal 1. 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리..

Effective Java 7. 다 쓴 객체 참조를 해제하라
2022. 1. 22. 21:03
Java/Effective Java
Stack으로 본 객체 참조 해제 아래의 Stack 클래스 코드를 확인해보고 문제가 될 만한 부분을 찾아보자. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size == 0) { throw new EmptyStackException();..

Effective Java 6. 불필요한 객체 생성을 피하라
2022. 1. 6. 23:34
Java/Effective Java
불필요한 객체 생성은 왜 피해야 할까? 똑같은 기능의 객체를 매번 생성하기 보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 재사용은 빠르고 세련되다. 특히 불변 객체(아이템 17) 은 언제든 재사용할 수 있다. 방법 1. String 객체는 새로 생성하지 말자 // 1. 잘못된 예 String s = new String("bikini"); // 2. 옳은 예 String s = "bikini"; 1번의 예시는 실행될 때마다 새로운 String 객체를 생성한다. 반복문이나 빈번히 호출되는 메서드의 경우 인스턴스가 수백만개 생성될 수 있다. 이러한 경우에는 새로운 인스턴스를 매번 생성하는 대신 하나의 String 인스턴스를 사용하자. 이 방식을 사용한다면 같은 가상 머신 안에서 똑같은 문자열 리터럴을 ..

Effective Java 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
2022. 1. 4. 00:10
Java/Effective Java
많은 클래스는 하나 이상의 자원에 의존한다. 예를 들어, 맞춤법 검사기를 생각해보자. 맞춤법 검사기는 사전에 의존한다. 따라서, 사전 하나로 모든 맞춤법 검사를 하는 것은 불가능하다. 맞춤법 검사는 사용하는 사전에 따라서 동작이 달라진다. 이러한 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. 이러한 경우, 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식인 의존 객체 주입을 사용한다. 샘플 코드 public class SpellChecker { private final Lexicon dictionary; public SpellChecker(Lexicon dictionary) { this.dictionary = dictionary; } //...

Effective Java 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
2022. 1. 2. 14:00
Java/Effective Java
언제 인스턴스화를 막는 것이 필요할까? 1. 단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때 사용한다. - 예를 들면, java.lang.Math, java.util.Arrays, java.util.Collections 2. 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩터리)를 모아놓는다. 3. final 클래스와 관련한 메서드들을 모아놓을 때 사용한다. - final 클래스를 상속해서 하위 클래스에 메서드를 넣는 것은 불가능하다. 그럼 어떻게 인스턴스화를 막을 수 있을까? 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어준다. 실제로 공개된 API들에서도 이처럼 의도치 않게 인스턴스화를 할 수 있게 된 클래스가 종종 있다. 1. 추상 클래스로 만드는..