카테고리 없음

[Java] 디자인 패턴

ekkkang 2025. 1. 9. 16:37

 

디자인 패턴(Design Patterns)은 소프트웨어 개발에서 자주 반복되는 문제들을 해결하기 위해 만들어진 재사용 가능한 코드 설계 방법입니다. 즉, 소프트웨어 설계 시 발생할 수 있는 문제를 효율적으로 해결하기 위한 설계의 모범 사례라고 할 수 있습니다.

 

 

장점

  • 개발자간의 원활한 소통
  • 소프트웨어 구조 파악이 용이
  • 재사용을 통한 개발 시간 단축
  • 설계 변경 요청에 대한 유연한 대처

단점

  • 객체지향 설계에 대한 깊은 이해도가 필요
  • 간단한 문제에 대해 디자인 패턴을 적용하는 것이 오히려 더 복잡하고 비효율적일 수 있습니다.
  • 모든 문제에 대해 디자인 패턴을 적용하는 것은 적절하지 않습니다.

디자인 패턴은 크게 생성(Creational), 구조(Structural), 행동(Behavioral)으로 구분할 수 있습니다.

 

 

생성 패턴

생성 패턴(Creational Pattern) : 객체 생성에 관련된 패턴으로, 객체가 생성되는 방식을 기본적인 형태에서 분리하여 코드의 유연성을 높입니다

Factory Method, Abstract Factory, Builder, Prototype, Singleton

 

구조 패턴

구조 패턴(Structural Pattern) : 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴입니다. 서로 다른 인터페이스를 가진 두 개의 객체를 함께 사용하거나, 객체들을 서로 묶어 새로운 기능을 제공하는 등의 역할을 합니다.

Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

 

행동 패턴

행동 패턴(Behavioral Pattern) : 객체나 클래스 사이의 알고리즘이나 책임 분배에 관련된 패턴입니다. 즉, 객체의 행동 패턴에 초점을 맞춥니다. Strategy, Template Method, Visitor, Iterator, Observer

 

 


콜백 메서드 직접 만들어 보기 

💡 학습 목표

1. 콜백 메서드의 개념과 동작 방식을 이해할 수 있다.
2. 콜백 메서드를 활용한 코드를 작성할 수 있다.
3. 콜백 메서드가 필요한 상황과 그 장점을 설명할 수 있다.

 

사전 기반 지식

  • 인터페이스: Java 인터페이스의 개념을 이해하고, 메서드를 선언하고 구현하는 방법을 알고 있어야 합니다.
  • 익명 클래스: 클래스 정의 없이 인터페이스를 바로 구현하는 익명 클래스의 사용법을 알고 있어야 합니다.

콜백 메서드 개념

콜백 메서드는 특정한 작업이 완료되었을 때 또는 특정 이벤트가 발생했을 때 호출되는 메서드입니다. 콜백 메서드는 주로 비동기 작업이나 이벤트 기반 시스템에서 사용됩니다. 콜백 메서드를 활용하면 동작을 정의하고 나중에 실행할 수 있기 때문에, 프로그램이 더 유연해지고 모듈화될 수 있습니다.

 


싱글톤 패턴을 만들어 보자

 

사전기반 지식

  • 클래스와 객체: 자바에서 클래스는 객체를 생성하기 위한 틀입니다. 일반적으로 하나의 클래스에서 여러 객체를 생성할 수 있지만, 싱글톤 패턴은 단 하나의 객체만을 보장합니다.
  • 생성자(Constructor): 객체가 생성될 때 호출되는 메서드로, 싱글톤 패턴에서는 생성자를 외부에서 호출하지 못하도록 제한합니다.
  • 정적 변수와 메서드: 싱글톤 패턴에서 주로 사용되는 정적(static) 멤버에 대한 이해가 필요합니다.
package design_patten;

// 싱글톤 패턴을 작성해보시오

// 1. 정적 변수를 선언한다.
// 2. private 생성자 선언한다.
// 3. 외부에서 접근할 수 있는 public 메서드를 만들어 준다.
public class SingleTon {

    // 1. 유일한 인스턴스를 저장할 변수를 선언한다. (private, static)
    private static SingleTon instance;

    // 2. 외부에서 객체를 생성하지 못 하도록 막기만 한다.
    private SingleTon() {}

    // 3. 외부에서 인스턴스 주소를 반환 받을 수 있는 메서드를 선언한다.
    public static SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }
        return instance;
    }

    public static void main(String[] args) {
        // 싱글톤 객체를 불러와 보자.

    }

}

 

package design_patten;

public class MainTest {
    // main <- 코드 시작 점
    public static void main(String[] args) {

        SingleTon singleTon1 = SingleTon.getInstance();
        SingleTon singleTon2 = SingleTon.getInstance();

        System.out.println(singleTon1);
        System.out.println(singleTon2);
        if (singleTon1 == singleTon2) {
            System.out.println("같은 객체가 맞아요");
        }
    }
}

 

 


어댑터 패턴 이란(Adapter Pattern)?

어댑터 패턴은 호환되지 않는 인터페이스를 가진 클래스들을 함께 동작할 수 있도록 변환해주는 디자인 패턴입니다. 즉, 기존 클래스의 인터페이스가 요구사항과 맞지 않을 때, 새로운 인터페이스를 기존 클래스에 맞추어 주는 역할을 합니다. 이를 통해 호환성 문제를 해결하고, 기존 코드를 수정하지 않고도 새로운 코드와 결합할 수 있습니다.

 

package design_patten.adapter;

interface IElectronic220v {
    void connect();
}

interface IElectronic110v {
    void connect();
}


public class MyHouse {

    // 정적 메서드
    // 집에 220v 전기 콘센트를 연결하는 메서드
    public static void homeConnect(IElectronic220v iElectronic220v) {
        // 콘센트 연결하는 행위
         iElectronic220v.connect();
    }

    // 메인 함수
    public static void main(String[] args) {

        HairDryer hairDryer = new HairDryer();
        AirConditioner airConditioner = new AirConditioner();
        ElectronicAdapter adapterHairDryer = new ElectronicAdapter(hairDryer);

        // 문제를 해결 해야 하는 부분
        homeConnect(adapterHairDryer);
        homeConnect(airConditioner);

    }

}

class HairDryer implements IElectronic110v {
    @Override
    public void connect() {
        System.out.println("헤어드라이어 연결 하기");
    }
}

class AirConditioner implements IElectronic220v {
    @Override
    public void connect() {
        System.out.println("에어컨 연결 220v");
    }
}

 

package design_patten.adapter;

// 핵심 개념
// 어댑터 클래스는 두 객체 간의 중재자로서, 서로 다른 인터페이스를 가진 객체들을
// 함께 동작하게 만들 수 있다.

// 우리 코드상에서 : 110v 전압과 220v 전압에서 사용할 수 있도록 중간 역할을 시킨다.

// 1. 내가 최종 쓰고자 하는 인터페이스를 구현 한다.
public class ElectronicAdapter implements IElectronic220v {

    // 2. 실제 기기 어댑터 내부에 전압 변경 기능이 있다.
    private IElectronic110v electronic110v;

    // 어! 이녀석 생성시에 강제성 110v 타입을 가진 녀석만 들어 올 수 있다.
    public ElectronicAdapter(IElectronic110v electronic110v) {
        this.electronic110v = electronic110v;
    }

    @Override
    public void connect() {
        System.out.println("어댑터를 통해 110v 타입의 기기를 220v 스펙에 연결합니다.");
        electronic110v.connect();
    }
}