[java] 클래스와 객체의 관련 디자인 패턴에 대해 설명해주세요.

디자인 패턴은 소프트웨어 개발에서 반복적으로 발생하는 문제들을 해결하기 위한 일종의 해결책이다. 클래스와 객체의 관련된 디자인 패턴은 객체지향 프로그래밍에서 클래스와 객체를 설계하고 사용하는 방법을 개선하고 재사용성을 높이기 위한 패턴들을 의미한다.

다음은 몇 가지 유용한 클래스와 객체의 디자인 패턴이다:

1. 팩토리 디자인 패턴 (Factory Design Pattern)

팩토리 디자인 패턴은 객체 생성을 캡슐화하고 클라이언트 코드가 구체적인 클래스를 알 필요가 없도록 도와준다. 팩토리 메서드를 사용하여 객체를 생성하고 반환함으로써 코드의 유연성을 높일 수 있다.

public interface Shape {
    void draw();
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class ShapeFactory {
    public Shape createShape(String shapeType) {
        if (shapeType.equalsIgnoreCase("Rectangle")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("Circle")) {
            return new Circle();
        }
        return null;
    }
}

public class Client {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();
        
        Shape rectangle = factory.createShape("Rectangle");
        rectangle.draw(); // Output: Drawing a rectangle
        
        Shape circle = factory.createShape("Circle");
        circle.draw(); // Output: Drawing a circle
    }
}

2. 싱글톤 디자인 패턴 (Singleton Design Pattern)

싱글톤 디자인 패턴은 어플리케이션이 단 하나의 인스턴스만을 가지도록 보장하는 디자인 패턴이다. 주로 자원을 공유하고 중복 생성을 방지하기 위한 목적으로 사용된다.

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // private constructor to prevent instantiation from outside
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

public class Client {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        
        System.out.println(singleton1 == singleton2); // Output: true
    }
}

3. 어댑터 디자인 패턴 (Adapter Design Pattern)

어댑터 디자인 패턴은 인터페이스 호환성 문제를 해결하기 위한 패턴이다. 이미 존재하는 클래스들을 새로운 클래스에 재사용하기 위해 인터페이스를 변환해주는 역할을 한다.

public interface MediaPlayer {
    void play(String filename);
}

public interface AdvancedMediaPlayer {
    void playVlc(String filename);
    void playMp4(String filename);
}

public class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String filename) {
        System.out.println("Playing vlc file: " + filename);
    }

    @Override
    public void playMp4(String filename) {
        // do nothing
    }
}

public class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String filename) {
        // do nothing
    }

    @Override
    public void playMp4(String filename) {
        System.out.println("Playing mp4 file: " + filename);
    }
}

public class MediaAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer.playVlc(audioType);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer.playMp4(audioType);
        }
    }
}

public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType) {
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file: " + audioType);
        } else if (audioType.equalsIgnoreCase("vlc")
                || audioType.equalsIgnoreCase("mp4")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType);
        } else {
            System.out.println("Invalid media type: " + audioType);
        }
    }
}

public class Client {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        
        audioPlayer.play("mp3"); // Output: Playing mp3 file: mp3
        audioPlayer.play("vlc"); // Output: Playing vlc file: vlc
        audioPlayer.play("mp4"); // Output: Playing mp4 file: mp4
        audioPlayer.play("avi"); // Output: Invalid media type: avi
    }
}

참고 자료