디자인 패턴(Design Pattern)-생성패턴

SUIN·2023년 9월 12일
0

디자인패턴

목록 보기
2/2
post-thumbnail

오늘은 디자인패턴 중에서 생성패턴에 대해서 공부해 볼 예정입니다.
이전 글에서 디자인패턴은 생성,구조,행위로 분류되고, 그 안에서도 여러개의 패턴이 존재한다고 이야기하였습니다.
대체적인 생성패턴의 종류는 다음과 같았습니다.

생성 패턴의 종류
추상 팩토리
팩토리
빌더
프로토타입
싱글톤

다 살펴보긴 어려우니(왜냐하면 제가 너무 괴로워서요) 오늘은 다섯가지 중에서도 널리 사용되는 팩토리/싱글톤 패턴의 개념을 알아보도록 하겠습니다.

팩토리 메서드

: 객체의 생성을 서브클래스(Factory)로 캡슐화하여 대신 처리를 맡기는 패턴

여기서 서브 클래스인 팩토리 클래스는 메인에서 직접 new연산자로 객체를 생성하는 대신 팩토리 클래스에서 생성을 도맡습니다. 여기서 넘어오는 값에 따라 각자 가른 객체를 생성시킵니다

예시

팩토리 메서드는 말 그대로 공장과 같은 의미로, 로봇(객체)이라는 개념과 로봇을 생성하는 공장(팩토리). 그리고 로봇에 대한 DIY도안(메인)이 있다면 DIY도안을 공장에 요청하여 로봇을 생성하는 것과 같습니다!

구현

//클래스 만들기
public abstract class RobotFactory {
	abstract Robot createRobot(String name);
}
//서브 클래스(팩토리클래스) 만들어서 생성 넘기기
public class SuperRobotFactory extends RobotFactory {
	@Override
	Robot createRobot(String name) {
		switch(name) {
		case "super" :
			return new SuperRobot();
		case "power" :
			return new PowerRobot();
		}
		return null;
	}
}

위처럼 생성하는 녀석과 본체를 따로 만들어주면 됩니다.

장단점

  • 클래스 생성과 사용을 분리하여 결합도를 낮춤
  • 캡슐화를 통한 정보 은닉처리가 가능
  • 시용자에게 라이브러리 또는 프레임워크 구성요소의 확장성을 제공
  • 기존 객체의 재구성이 아닌 기존객체를 재사용한 생성이 가능하게 함으로써 리소스의 절약이 가능
  • 단일 채임 원칙, 개방/폐쇄원칙에 부합함
  • 코드의 복잡성이 증가함
  • 구현체마다 객체들을 모두 구현해야하기 때문에 구현체가 늘어날 때마다 팩토리 클래스가 계속적으로 늘어남

리뷰

캡슐화를 통한 은닉처리, 생성과 사용의 분리로 인한 협업기능성 향상이라는 특징들을 보았을 때, 실제로 사용자들에게 보여질 수 있는 서비스를 개발할 때 정말 유용하게 사용될 것 같은 패턴이라는 생각이 들었습니다. 코드가 복잡해질 수는 있다고 하더라도 코드를 따로 분리한다는 것 자체가 저는 코드를 작성할 때는 괴롭겠지만 보는 사람들에게는 정말 보기 좋을 것 같아서 자주 적용해보면서 연습하면 좋을 것 같습니다ㅎㅎ


싱글톤

: 단 하나의 유일 객체를 만들기 위한 패턴.

이전에 생성한 적이 있던 인스턴스가 필요한 경우 인스턴스를 새롭게 만들지 않고 재활용합니다.(전역변수와 같은 개념!)
싱글톤 패턴은 해당 객체가 많은 곳에서 범용적으로 사용되는 무거운 존재일 때 사용하는 것이 적합합니다.

예시

  • 데이터베이스 연결 모듈, 디스크 연결, 네트워크 통신, 로그 기록 객체 등에 활용됩니다!
  • 안드로이드 스튜디오 자바 SDK에서는 액티비티, 클래스마다 주요 클래스들을 하나하나 전달하는게 번거롭기 때문에 싱글톤 클래스를 만들어 어디서든 접근하도록 설계합니다.

구현

new생성자를 통한 인스턴스를 제한하기 위해 생성자 메서드에 private키워드를 붙여줍니다! 그럼 끗!
사용 예제는 아래와 같습니다.

#include <iostream>

class Singleton {
private:
    Singleton() {}
    Singleton(const Singleton& ref) {}
    Singleton& operator=(const Singleton& ref) {}
    ~Singleton() {}
public:
    static Singleton& getIncetance() {
        static Singleton s;
        return s;
    }
};

int main(void) {
    Singleton& s = Singleton::getIncetance();
    return 0;
}

이처럼 코드를 작성하면, 아무리 여러 개의 싱글톤에서 생성자인 getInstance를 불러와서 저장해도 같은 주소 값이 저장됩니다.(하나의 객체로 여러 변수에 활용!)

구현 방법의 다양성

싱글톤 패턴을 구현하는 방법은 예제를 포함한 총7가지의 방법이 있습니다.
1. Eager Initialization
2. Static block initialization
3. Lazy initialization
4. Thread safe initialization
5. Double-Checked Locking
6. Bill Pugh Solution
7. Enum 이용
위의 7가지 중 가장 검증되고 좋은 패턴은 하단의 6,7번이라고 할 수 있겠습니다.
자세한 구현 방법에 관해서는 .. 생략하도록 하겠습니다.
하지만 해당 예제들이 궁금하시다면 하단의 참고자료 사이트로 확인해주시면 감사하겠습니다

장단점

  • 메모리 절약
  • 데이터의 공유에 용이
  • 모듈 간의 의존성이 높아짐
  • 모듈 테스트의 어려움
  • 추가 단점: SOLID원칙에 위배되는 경우가 많습니다. 이전에 말씀드린 SOLID원칙 중 인스턴스 하나 당 하나의 책임을 져야하는 단일책임원칙, 클래스간의 독립성을 지켜야하는 개방-폐쇄원칙에 위배되는 경우가 많습니다. 또한 의존 역전의 원칙 또한 위반할 수 있기 때문에 굉장히 유의해야할 점이 많습니다.

리뷰

전체적으로 장점 또한 존재하지만 SOLID원칙에 위배된다는 점 등으로 인해 싱글톤 패턴은 좋지 않은 패턴이라고 불리기도 한다고 합니다.. 항상 유의하며 사용해야할 패턴 중에 하나인 것 같습니다!


나머지도 전체적으로 리뷰하고 싶으나 그렇게까지 완벽하게 하면 제가 하루만에 벨로그 관둘지도 몰라서요(이번 글도 1달 만에 올라옴)
차근차근 배우고 보충할 수 있도록 하겠습니다!!

참고자료
팩토리

profile
공부하기싫을때붙잡고공부해봤자비명밖에안나옵니다지금제가그래요

0개의 댓글