디자인패턴 이란?
프로그램 개발에서 자주 나타나는 과제를 해결하기 위한 방법 중 하나로,
과거의 소프트웨어 개발 과정에서 발견된 설계의 노하우를 축적하여 이름을 붙여,
이후에 재이용하기 좋은 형태로 특정의 규약을 묶어서 정리한 것.
간단히 말해 소프트웨어 설계할 때 또는 프로그램 개발과정에서
특정 부분에서 많이 발생하는 문제를 정리하여 상황에 따라 해결할 수 있는 해결책(패턴)
* 패턴
: 다양한 소프트웨어들로 각기 다른 프로그램을 개발하는 과정에서 공통적인 문제점 또는 유사한 문제점이 존재하여 이를 처리하는 과정도 공통점이 있는데 이러한 유사점을 패턴이라고 한다.
더 우아하고 더 빠른 개발을 할 수 있다.
디자인패턴 구조
- 콘텍스트(context)
문제가 발생하는 여러 상황.
즉, 패턴이 적용될 수 있는 상황을 말한다.
경우에 따라서는 패턴이 유용하지 못한 상황을 말하기도 한다.
- 문제(problem)
패턴이 적용되어 해결될 필요가 있는 여러 디자인 이슈들을 말한다.
이때 여러 제약 사항과 영향력도 문제 해결을 위해 고려해야 한다.
- 해결(solution)
문제를 해결하도록 설계를 구성하는 요소들과 그 요소들 사이의 관계, 책임, 협력 관계를 말한다.
해결은 반드시 구체적인 구현 방법이나 언어에 의존적이지 않으며 다양한 상황에 적용할 수 있는 일종의 템플릿
PHP에서 쓰이는 디자인패턴
1. 팩토리(Factory) - 생성 패턴
: 객체 생성 처리를 서브 클래스로 분리해 처리하도록 캡슐화하는 패턴
<?php
class Automobile
{
private $vehicleMake;
private $vehicleModel;
public function __construct($make, $model)
{
$this->vehicleMake = $make;
$this->vehicleModel = $model;
}
public function getMakeAndModel()
{
return $this->vehicleMake . ' ' . $this->vehicleModel;
}
}
class AutomobileFactory
{
public static function create($make, $model)
{
return new Automobile($make, $model);
}
}
// Automobile 객체를 생성하는 팩토리 사용
$veyron = AutomobileFactory::create('Bugatti', 'Veyron');
print_r($veyron->getMakeAndModel(); //"Bugatti Veyron" 출력
Automobile 객체를 생성할 때 팩토리를 사용하고 있다.
장점
- Automobile 클래스 이름을 바꾸거나, 변경이 생기거나, 다른 클래스로 대체해도 Automobile 클래스를 사용하는 모든 곳의 코드를 고치지 않고 팩토리 클래스에 있는 코드만 수정하면 된다.
- 생성하는 과정이 복잡한 클래스 객체라고 해도 그런 코드가 팩토리에만 있고 그 클래스를 생성하는 모든 곳에 반복적으로 복잡한 코드를 넣지 않아도 된다.
2. 싱글턴(Singleton) - 생성 패턴
: 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴
웹 어플리케이션을 설계할 때 특정 클래스의 경우에는 오직 하나의 인스턴스만이 존재하여 모든 곳에서 그 인스턴스만을 사용해야 한다는 결정이 의미있는 경우가 있다. 싱글톤 패턴을 사용하여 그런 클래스를 만들어 낸다.
<?php
class Singleton {
private static $instance = null;
private function __construct()
{
// The expensive process (e.g., db connection) goes here.
}
public static function getInstance()
{
if(self::$instance == null)
{
self::$instance = new Singleton();
}
return self::$instance;
}
}
클래스에서 생성할 수 있는 객체의 수를 하나만으로 제한하기 때문에 모든 변수가 동일한 단일 객체를 가리키는 것으로 끝난다.
<?php
// singleton
$instance = ConnectDb::getInstance();
$conn = $instance->getConnection();
var_dump($conn);
// without singleton
$instance = new ConnectDbWOSingleton();
$conn = $instance->getConnection();
var_dump($conn);
싱글톤을 사용하지 않으면 새 개체를 만들 때마다 새 데이터베이스 연결을 설정해야 한다.
이는 데이터베이스와의 새로운 연결에 시간이 소요되기 때문에 시스템 속도를 저하시키는 의미가 있다.
싱글톤 패턴을 사용할 때 주의해야 할 것은,
패턴의 특성상 어플리케이션 전체 범위에 영향을 주는 일종의 상태 정보가 생긴다는 것.
이런 특성 때문에 테스트 가능성을 떨어뜨린다.
대부분의 경우에는 싱글톤 클래스 대신 의존성 주입(Dependency Injection)을 사용할 수 있으므로
가능하다면 싱글톤을 피하는 편이 좋다.
의존성 주입을 사용하게 되면 공유되는 리소스를 사용하는 클래스라고 해도 구체적인 싱글톤 클래스의 구현에 의존적이지 않게 되므로 설계적으로 더 낫다.
3. 전략(Strategy) - 행동 패턴
: 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
전략 패턴으로 특정한 알고리즘을 캡슐화 할 수 있다.
그 결과 사용하는 쪽에서는 알고리즘의 실제 구현에 대해 전혀 모르는 채로도 특정 알고리즘을 실체화하여 사용할 수 있다.
<?php
interface OutputInterface
{
public function load();
}
class SerializedArrayOutput implements OutputInterface
{
public function load()
{
return serialize($arrayOfData);
}
}
class JsonStringOutput implements OutputInterface
{
public function load()
{
return json_encode($arrayOfData);
}
}
class ArrayOutput implements OutputInterface
{
public function load()
{
return $arrayOfData;
}
}
배열이나 json을 직렬화하거나, 그냥 배열을 내보낼 때 예제
이처럼 알고리즘을 캡슐화 함으로써 다른 개발자들은 알고리즘을 사용하고 있는 코드에 영향을 주지 않고도
새로운 출력 형식을 추가할 수 있게 된다.
각각의 '출력' 클래스들이 어떻게 OutputInterface 를 구현하고 있는지 볼 수 있는데, 이러한 방식에 두 가지 목적이 있다.
- 각각의 출력 클래스 구현체들이 준수해야하는 구현 규칙을 제공
- 공통적으로 'OutputInterface' 인터페이스를 구현함으로써 타입 힌팅(파라미터와 리턴값의 데이터 값을 명시적으로 지정)을 통해 알고리즘을 사용하는 코드 쪽도 정확한 타입을 사용하도록 보장
4. 프론트 컨트롤러(Front Controller)
: 웹 어플리케이션으로 오는 모든 리소스를 처리해주는 하나의 진입점(index.php)을 두는 패턴.
컨트롤러에서는 모든 의존 관계를 로딩하고, HTTP 요청을 처리한 후 응답을 보내주는 것 까지의 과정을 책임진다.
- 코드가 잘 모듈화되는 경향
- 모든 요청에 대해서 항상 수행되어야 하는 작업(입력 값에서 위험한 데이터를 걸러내는 등의 작업)을 수행시킬 수 있는 중심점으로서 컨트롤러를 생각할 수 있다는 이점
5. 모델-뷰-컨트롤러(MVC, Model-View-Controller)
: MVC 패턴과 이 패턴의 변형이라고 할 수 있는 HMVC나 MVVM 패턴은 어플리케이션 코드들을 특정 역할을 수행하는 논리적인 단위로 구분
- 모델(model) : 데이터에 접근하는 레이어로서 데이터소스에서 데이터를 가져와, 어플리케이션에서 사용할 수 있는 형태로 만든 데이터를 제공
- 뷰(view) : 웹 브라우저에게 응답으로 제공되는 템플림(마크업, XML, JSON 등)을 표시
- 컨트롤러(Controller) : HTTP 요청을 받고, 모델로부터 얻은 데이터를 처리하고, '뷰'를 로드하여 응답을 보낸다.
* MVVM(Model-View-View-Model)
: 안드로이드 어플리케이션의 기본 디자인 패턴이다.
UI와 로직의 분리로, 유지보수 및 개발 효율을 높일 수 있다.
*HMVC(Hierarchical model-view-controller)
: 계층형 MVC, 폴더 하나에서 컨트롤러별 서브 폴더로 확장한 개념
각 컨트롤러별 MVC를 두게 되어 모듈화가 장점이다. 필요한 기능이 있다면 해당 모듈만 복붙하여 수정 가능.
단점으로는 라이브러리 의존도가 추가 된다.
참고사이트
https://modernpug.github.io/php-the-right-way/pages/Design-Patterns.html
https://effortguy.tistory.com/182
https://helloworld-88.tistory.com/291
https://treewebsolutions.com/articles/the-singleton-pattern-in-php-65
https://cikorea.net/bbs/view/qna?idx=11734&view_category=&lists_style=
'PHP' 카테고리의 다른 글
[Laravel/PHP] Scope ? (0) | 2022.12.12 |
---|---|
str_replace / preg_replace (0) | 2022.09.14 |
PHP Excel 라이브러리 (0) | 2022.08.17 |
PHP 구성 (0) | 2022.08.16 |
모던 PHP 란? (0) | 2022.08.14 |