개요
개발자로서 자바로 코딩을 하다 보면, 효율적이고 유지보수하기 쉬운 코드를 작성하는 것이 중요하다. 그 과정에서 자주 등장하는 것이 디자인 패턴(Design Pattern)이다. 처음에는 디자인 패턴이란 용어가 생소하게 느껴질 수 있지만, 개발 환경에서 마주치는 반복적인 문제들을 해결하는 데 큰 도움이 된다. 이번 글에서는 자바의 디자인 패턴에 대한 기본 개념을 쉽게 풀어 설명하려 한다. 디자인 패턴을 이해하고 나면 코드 작성과 구조화에 훨씬 자신감이 생길 것이다.
디자인 패턴이란 무엇인가?
디자인 패턴은 소프트웨어 개발에서 반복적으로 발생하는 문제를 해결하기 위한 일반화된 해결책이다. 디자인 패턴을 사용하면 코드의 재사용성이 높아지고, 유지보수가 쉬워지며, 다른 개발자와 협업할 때도 일관성을 유지할 수 있다. 이는 오랜 경험을 통해 검증된 패턴들이기 때문에, 복잡한 문제를 더 쉽게 해결할 수 있다.
디자인 패턴은 크게 세 가지로 분류된다:
- 생성 패턴(Creational Patterns): 객체 생성 방식을 설계하는 패턴
- 구조 패턴(Structural Patterns): 객체 간의 관계를 조직하는 패턴
- 행위 패턴(Behavioral Patterns): 객체 간의 상호작용을 제어하는 패턴
생성 패턴(Creational Patterns)
생성 패턴은 객체 생성 방식을 캡슐화하여, 코드 변경 없이 다양한 방법으로 객체를 생성할 수 있게 해준다. 가장 많이 사용되는 생성 패턴 중 하나는 싱글턴(Singleton) 패턴이다.
싱글턴 패턴은 하나의 클래스에 대해 오직 하나의 인스턴스만 존재하도록 보장한다. 이 패턴은 주로 설정 정보를 공유하거나, 로그와 같은 리소스를 전역적으로 관리할 때 사용된다.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
위 코드에서 getInstance() 메서드는 객체를 한 번만 생성하고, 이후에는 동일한 객체를 반환하는 것을 보장한다.
구조 패턴(Structural Patterns)
구조 패턴은 클래스나 객체들을 조합해 더 큰 구조를 형성하는 방법을 제공한다. 이 패턴은 서로 다른 클래스들 사이의 관계를 쉽게 설정하고, 더 복잡한 구조를 단순하게 표현하는 데 사용된다.
대표적인 구조 패턴 중 하나는 데코레이터(Decorator) 패턴이다. 이 패턴은 객체에 기능을 동적으로 추가할 수 있게 해준다.
public interface Component {
void operation();
}
public class ConcreteComponent implements Component {
public void operation() {
System.out.println("기본 기능");
}
}
public class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedFunctionality();
}
private void addedFunctionality() {
System.out.println("추가된 기능");
}
}
위 코드에서, ConcreteComponent에 기본 기능이 있고, ConcreteDecorator는 이 기본 기능에 추가 기능을 더하는 방식으로 동작한다. 이러한 패턴을 사용하면 기존 클래스의 코드를 변경하지 않고도 새로운 기능을 추가할 수 있다.
행위 패턴(Behavioral Patterns)
행위 패턴은 객체 간의 상호작용 방식을 정의하는 패턴이다. 객체들이 어떻게 협력하고, 그들 사이에서 어떤 책임을 수행할지를 관리한다. 가장 자주 사용되는 패턴 중 하나는 옵저버(Observer) 패턴이다.
옵저버 패턴은 객체의 상태 변화에 따라 다른 객체들이 자동으로 알림을 받도록 하는 패턴이다. 주로 이벤트 처리 시스템에서 사용된다.
import java.util.ArrayList;
import java.util.List;
public class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
public class ConcreteObserver extends Observer {
public ConcreteObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
public void update() {
System.out.println("상태 변경됨: " + subject.getState());
}
}
위 코드를 보면, Subject가 상태를 변경할 때마다 연결된 Observer들이 자동으로 업데이트되는 방식으로 동작한다. 이는 특히 이벤트 기반 시스템에서 유용하다.
정리
이번 글에서는 자바의 디자인 패턴에 대해 개요를 살펴보았다. 디자인 패턴은 코드의 재사용성과 유지보수성을 높이는 데 큰 도움이 된다. 각 패턴의 특징과 활용 방법을 이해하고, 적절히 적용한다면 더 나은 소프트웨어 개발이 가능할 것이다.
코드를 리팩토링 할때, 새로운 기능을 개발할 때 등과 같은 상황에서 코드부터 작성하기 보다는 위와 같은 패턴들 중 어떤것을 적용할 수 있는지 생각해보고 시작하는 편도 좋은 방법인것 같다.
'Java' 카테고리의 다른 글
결제 동시성 이슈 해결 - 분산락과 Redisson (1) | 2024.10.03 |
---|---|
[Java] 버전 별 Map 선언 방법 (1) | 2024.09.27 |
자바에서 불변 객체(Immutable Object) 만들기 (0) | 2024.09.25 |
[Java] 자바에서 Optional의 올바른 사용법 (0) | 2024.09.24 |
[Java] 공통 적용 JsonDeserializer 만들어 보기 (4) | 2024.09.23 |
댓글