본문 바로가기
Everyday Study

2024.08.06 (화) { 팩토리 메서드 패턴, 싱글톤패턴, 프로토타입패턴, CSV&JSON }

by xogns93 2024. 8. 6.

팩토리 메서드 패턴 (Factory Method Pattern)

팩토리 메서드 패턴은 객체 생성의 인터페이스를 정의하되, 구체적인 클래스의 인스턴스를 만드는 작업은 서브클래스에서 수행하도록 하는 생성 패턴입니다. 이를 통해 객체 생성 코드를 추상화하고, 객체 생성의 책임을 서브클래스에 위임하여 코드의 유연성과 확장성을 높입니다.

주요 개념

  1. Creator (창조자): 객체 생성을 위한 팩토리 메서드를 선언하는 추상 클래스 또는 인터페이스.
  2. ConcreteCreator (구체적 창조자): Creator를 상속하거나 구현하며, 팩토리 메서드를 오버라이드하여 구체적인 제품 객체를 생성하는 클래스.
  3. Product (제품): 팩토리 메서드에 의해 생성되는 객체의 타입을 정의하는 인터페이스 또는 추상 클래스.
  4. ConcreteProduct (구체적 제품): Product 인터페이스를 구현하는 구체적인 클래스.

싱글톤

싱글톤(Singleton) 패턴은 특정 클래스의 인스턴스가 오직 하나만 존재하도록 보장하는 디자인 패턴입니다. 이는 주로 전역 상태를 관리하거나 공통 리소스를 관리하는 데 사용됩니다. 싱글톤 패턴은 객체 지향 프로그래밍에서 중요한 패턴 중 하나이며, 주로 자원 관리, 로깅, 설정 관리 등에 사용됩니다.

싱글톤 패턴의 특징

  1. 유일성 보장: 특정 클래스의 인스턴스가 하나만 존재하도록 보장합니다.
  2. 전역 접근: 애플리케이션 전체에서 동일한 인스턴스를 공유하여 사용할 수 있습니다.
  3. 지연 초기화: 필요한 시점에 인스턴스를 생성하여 리소스를 효율적으로 사용할 수 있습니다.

싱글톤 패턴 구현 방법

싱글톤 패턴은 여러 가지 방법으로 구현될 수 있습니다. Java에서의 구현 예제를 통해 설명하겠습니다.

기본 싱글톤 패턴

public class Singleton {
    // 클래스의 유일한 인스턴스를 저장하는 정적 변수
    private static Singleton instance;

    // 외부에서 인스턴스를 생성하지 못하도록 생성자를 private으로 선언
    private Singleton() {
        // 초기화 코드
    }

    // 유일한 인스턴스를 반환하는 정적 메서드
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 기타 메서드
    public void showMessage() {
        System.out.println("Hello from Singleton!");
    }
}

사용 예제

public class Main {
    public static void main(String[] args) {
        // Singleton 인스턴스를 가져옴
        Singleton singleton = Singleton.getInstance();
        singleton.showMessage();
    }
}

출력

Hello from Singleton!

 

 


프로토타입 패턴(Prototype Pattern)

프로토타입 패턴(Prototype Pattern)은 생성 디자인 패턴 중 하나로, 객체를 직접 생성하는 대신, 기존 객체를 복제하여 새로운 객체를 생성하는 패턴입니다. 이 패턴은 주로 객체 생성 비용이 높거나 복잡한 초기화 과정을 거치는 경우에 유용하게 사용됩니다.

프로토타입 패턴의 주요 특징

  1. 객체 복제: 새로운 객체를 생성할 때, 기존 객체를 복제하여 생성합니다.
  2. 고성능: 객체를 복제하여 생성하므로, 객체 생성 비용이 절감될 수 있습니다.
  3. 다형성: 복제된 객체는 원본 객체와 동일한 인터페이스를 구현하므로, 다형성을 유지할 수 있습니다.

프로토타입 패턴의 구현 방법

Java에서는 Cloneable 인터페이스와 clone() 메서드를 사용하여 프로토타입 패턴을 구현할 수 있습니다.

1. 프로토타입 인터페이스 정의

프로토타입 패턴에서 사용될 인터페이스를 정의합니다.

public interface Prototype extends Cloneable {
    Prototype clone();
}

2. 구체적인 프로토타입 클래스 구현

Prototype 인터페이스를 구현하는 클래스는 clone() 메서드를 재정의하여 객체 복제를 수행합니다.

public class ConcretePrototype implements Prototype {
    private String field;

    public ConcretePrototype(String field) {
        this.field = field;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("Clone not supported", e);
        }
    }
}

3. 클라이언트 코드

클라이언트 코드는 프로토타입 객체를 복제하여 새로운 객체를 생성합니다.

public class PrototypeDemo {
    public static void main(String[] args) {
        // 원본 객체 생성
        ConcretePrototype original = new ConcretePrototype("Original");
        System.out.println("Original field: " + original.getField());

        // 객체 복제
        ConcretePrototype cloned = (ConcretePrototype) original.clone();
        System.out.println("Cloned field: " + cloned.getField());

        // 복제된 객체의 필드 값 변경
        cloned.setField("Cloned");
        System.out.println("Modified cloned field: " + cloned.getField());
        System.out.println("Original field after modification: " + original.getField());
    }
}

출력

Original field: Original
Cloned field: Original
Modified cloned field: Cloned
Original field after modification: Original

프로토타입 패턴의 장단점

장점:

  1. 객체 생성 비용 절감: 복잡한 객체를 새로 생성하는 대신, 기존 객체를 복제하여 생성하므로 비용을 절감할 수 있습니다.
  2. 간단한 객체 생성: 객체 복제를 통해 간단하게 새로운 객체를 생성할 수 있습니다.
  3. 다형성: 복제된 객체는 원본 객체와 동일한 인터페이스를 구현하므로, 다형성을 유지할 수 있습니다.

단점:

  1. 복제 메서드 구현: clone() 메서드를 구현해야 하며, 이를 잘못 구현할 경우 예상치 못한 문제를 일으킬 수 있습니다.
  2. 복제 객체 관리: 복제된 객체의 상태를 적절히 관리하지 않으면, 원본 객체와 복제 객체 간의 상태 불일치가 발생할 수 있습니다.

결론

프로토타입 패턴은 객체 생성 비용이 높은 상황에서 유용하게 사용될 수 있는 디자인 패턴입니다. 이 패턴을 통해 기존 객체를 복제하여 새로운 객체를 생성함으로써 성능을 개선하고, 객체 생성 과정을 단순화할 수 있습니다. Java에서는 Cloneable 인터페이스와 clone() 메서드를 활용하여 프로토타입 패턴을 구현할 수 있으며, 이를 통해 객체의 복제와 관리를 효과적으로 수행할 수 있습니다.

 


CSV(Comma-Separated Values) 파일

CSV(Comma-Separated Values) 파일은 2차원 데이터를 텍스트 형식으로 저장하는 파일 형식 중 하나로, 각 데이터 항목이 쉼표로 구분됩니다. CSV 파일은 주로 스프레드시트 프로그램(예: Microsoft Excel, Google Sheets)에서 데이터를 저장하고 교환하는 데 사용됩니다. CSV 파일은 행과 열로 구성된 데이터를 직관적으로 표현할 수 있으며, 데이터베이스와 프로그래밍 언어에서도 널리 사용됩니다.

CSV 파일 형식

CSV 파일의 각 행은 데이터 레코드를 나타내며, 각 행의 항목은 쉼표로 구분됩니다. CSV 파일의 예시는 다음과 같습니다:

Name,Age,Location
John Doe,28,New York
Jane Smith,34,Los Angeles
Emily Jones,22,Chicago

위 예제에서 첫 번째 행은 헤더 행으로, 각 열의 이름을 나타냅니다. 이후의 행들은 실제 데이터 레코드입니다.

 


JSON (JavaScript Object Notation)

  • 경량 데이터 교환 형식.
  • 키-값 쌍으로 데이터를 표현
  • 대부분의 프로그래밍 언어에서 쉽게 파싱 및 생성 가능.
  • 구조: 객체는 중괄호 {}로, 배열은 대괄호 []로 감싸며, 키-값 쌍은 콜론 :으로 구분.

예:

{
    "name": "John",
    "age": 30,
    "city": "New York"
}

 

파이썬의 딕셔너리

  • 파이썬의 내장 데이터 타입.
  • 키-값 쌍으로 데이터를 저장
  • 중괄호 {}로 감싸며, 콜론 :으로 키와 값을 구분.

예:

data = {
    "name": "John",
    "age": 30,
    "city": "New York"
}

 

JSON과 XML 비교

 

JSON:

  • 경량 데이터 형식.
  • 사람이 읽기 쉽고, 작성하기 쉬움.
  • 구조가 간단하며, 데이터 직렬화 및 역직렬화가 빠름.
  • 기본적으로 스키마가 없음. (필요 시 JSON Schema를 사용할 수 있음)
  • 다양한 프로그래밍 언어에서 지원.

XML (eXtensible Markup Language):

  • 계층적 데이터 표현에 적합.
  • 사람이 읽기 어렵고, 작성하기 복잡할 수 있음.
  • 태그를 사용하여 데이터를 구조화.
  • 명시적인 스키마를 가질 수 있음 (예: DTD, XSD).
  • 데이터 유효성 검사가 더 강력함.
  • 데이터 크기 및 파싱 속도가 느릴 수 있음.

예제 비교

JSON 예제:

{
    "name": "John",
    "age": 30,
    "address": {
        "city": "New York",
        "zipcode": "10001"
    },
    "phoneNumbers": ["123-456-7890", "987-654-3210"]
}

XML 예제:

<person>
    <name>John</name>
    <age>30</age>
    <address>
        <city>New York</city>
        <zipcode>10001</zipcode>
    </address>
    <phoneNumbers>
        <phoneNumber>123-456-7890</phoneNumber>
        <phoneNumber>987-654-3210</phoneNumber>
    </phoneNumbers>
</person>

JSON과 파이썬 딕셔너리 사용 예

JSON 파싱 및 생성 (파이썬):
파이썬에서는 json 모듈을 사용하여 JSON 데이터를 파싱하고 생성할 수 있습니다.

JSON 문자열을 파이썬 딕셔너리로 변환:

import json

json_string = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_string)

print(data)
# 출력: {'name': 'John', 'age': 30, 'city': 'New York'}

파이썬 딕셔너리를 JSON 문자열로 변환:

import json

data = {
    "name": "John",
    "age": 30,
    "city": "New York"
}

json_string = json.dumps(data)
print(json_string)
# 출력: {"name": "John", "age": 30, "city": "New York"}

요약

  • JSON: 경량 데이터 교환 형식으로, 파이썬의 딕셔너리와 구조적으로 유사함.
  • 파이썬 딕셔너리: 파이썬 내장 데이터 타입으로, JSON과 유사한 키-값 쌍 데이터 구조를 가짐.
  • XML: 데이터 유효성 검사와 계층적 데이터 표현에 강점이 있지만, JSON에 비해 무겁고 사람이 읽기 어려움.
  • JSON vs XML: JSON은 가볍고 간단하며 작성 및 파싱이 쉬운 반면, XML은 더 복잡하지만 데이터 구조와 유효성 검사가 강력함.

따라서 JSON은 사용이 편리하고 가볍지만, 특정 상황에서는 XML의 스키마 및 유효성 검사 기능이 더 유용할 수 있습니다.

JSON은 스키마가 없기때문에 쓰기에 훨씬 편하고 대신 속도가 XML 보다 느림