GOF - Builder

octofox·2021년 6월 2일
0

GOF - Gang Of Four

목록 보기
6/6
post-thumbnail

Builder

복합 객체를 만들어 보자!
Computer에는 Cpu, Ram, Storage가 있다.
3개의 부속 객체를 받아 Computer 라는 복합 객체를 완성한다.
복합객체를 만드는 과정에 재사용성 부여하자.
사실 재사용성이라... 아니 규격화라는 말이 더 잘 들어맞겠다.

Builder pattern은 크게 Builder, Algorism class 두 개로 구성된다.
Builder는 Algorism에 따라 다른 기능을 수행한다.
즉 Builder는 algorism에 의존한다.
algorism에 따라 builder는 다른 일들을 수행할 수 있다.

빌더 패턴은 복합 객체의 생성 로직을 별도 클래스로 분리하며, 분리한 로직을 알고리즘이라고 부립니다. 분리한 알고리즘 객체는 빌더에 전달되어 복합 객체를 생성합니다.

규격이 있지만 내용을 다르게, 결과는 다르게 나와야 규격(패턴)의 효용성이 있지 않은가?
모든 코드의 실행은 Builder class로만 이루어진다. algorism class에 직접 접근하지 않는다.
composite = 합성물
concrete = 구체성, 구체적인

재료

<?php
class Computer
{
    public $_cpu;
    public $_ram = [];
    public $_storage=[];
}
<?php
class Memory
{
    public $size;
    
    public function __contruct($size)
    {
        if($size)
        {
            $this->size = $size
        }
    }
}
<?php
class Storage
{
    public $size;
    
    public function __contruct($size)
    {
        if($size)
        {
            $this->size = $size
        }
    }
}

추상화

Builder의 중요하고 공통적인 함수들, 기능들은 추상화하자.

  1. Builder는 복합 객체를 alogorism을 사용하여 build() 한다.
    (build의 내용은 무엇을 만들 것인가에 따라 달라진다. 따라서 하위 class에서 구현된다. 다만 모든 Builder객체는 build 메소드를 가져야한다.)
  2. Builder는 자신이 사용할 algorism을 세팅한다.
  3. algorism에 따라 build된 객체, instance를 반환한다.
<?php
abstract class Builder
{
    // 알고리즘 객체 저장;
    protected $algorism;
    
    // 알고리즘 세팅
    public function setAlgorism(Algorism $algorism)
    {
        $this->algorism = $algorism;
        
        return $this;
    }
    
    // build된 객체, instance를 반환한다.
    public function getInstance()
    {    
        // 알고리즘도 getInstance 메소드가 있다.
        return $this->algorism->getInstance();
    }
    
    // 다형성을 위한 추상 메서드
    abstract public function build();
}

Algorism의 중요하고 공통적인 함수들, 기능도 추상화하자.

  1. 미완성된 복합체(부품이 없는 컴퓨터)를 가지고 있다.
  2. 복합체 instance를 반환한다.
  3. 부품객체들(Cpu, Ram, Storage)을 복합객체(Computer)에 합치는 기능들이 마련되어있다.
    (빌더에 들어가는 모든 알고리즘이 컴퓨터를 만들기 위한 것은 아니다. 고로 특수화, 자식 class에서 구현한다.)
<?php
abstract class Algorism
{
    // 복합체는 자식 class에서 초기화 된다.
    protected $Composite; // 영어로 '복합체'라는 뜻
    
    public function getInstance() // 알고리즘이 빌더에 반환해준다.
    {
        return $this->Composite;
    }
    
}

특수화

추상화를 끝내고 이제 나머지를 특수화 해보자
특수화는 abstract class를 상속받아서 작성한다.
컴퓨터 조립을 위한 Builder를 Factory라는 이름으로 특수화 해본다.

<?php
class Factory extends Builder
{
    // 알고리즘 위존성을 주입 받습니다.
    public funtion __construct($algorism = null)
    {
        if($algorism)
        {
            $this->algorism = $algorism;
        }
    }
    
    // 단계별 알고리즘의 메서드를 호출합니다
    piblic function build() // 물론 이곳으로 변수들을 받아도 됩니다
    {
        $this->algorism->setCpu("i7"); // 물론 이곳으로 변수들을 받아도 됩니다
        $this->algorism->setRam([8,8]); // 물론 이곳으로 변수들을 받아도 됩니다
        $this->algorism->setStorage([256,512]); // 물론 이곳으로 변수들을 받아도 됩니다.
        return $this;
    }
}
<?php

class ProductModel extends Algorism
{
    public function __construct()
    {
        $this->Composite = new Computer(); // 깡통 컴퓨터;
    }
    
    // build() 안에서 쓰일 메서드
    public function setCpu($cpu)
    {
        $this->Composite->_cpu = $cpu;
        return $this;
    }
    // build() 안에서 쓰일 메서드
    public function setRam($size)
    {
        foreach($size as $mem)
        {
            array_push($this->Composite->_ram, new Memory($mem));
        }
        return $this;
    }
    
    // build() 안에서 쓰일 메서드
    public function setStorage($size)
    {
        foreach($size as $disk)
        {
            array_push($this->Composite->_storage, new Storage($disk));
        }
        return $this;
    }
    
}

모두 작성됬다.
이제 실행코드를 만들어 보자.

실행 코드

<?php
require "Builder.php"; // 추상 클래스
require "Factory.php";

require "Computer.php";
require "Storage.php";
require "Memory.php";

require "Algorism.php"; // 추상 클래스
require "ProductModel.php";


// 빌더에 주입할 알고리즘을 먼저 생성합니다.
$alogorism = new ProductModel;

// 빌더를 생성합니다.
$factory = new Factory();
$factory->setAlgorism($algorism); // 생성자에 넘겨주어도 관계없다.

// 생성 요청
// 빌드된 객체를 전달 받습니다.
$computer = $factory->build()->getInstance(); // build()는 $this를 반환함으로 이 처럼 체이닝이 가능합니다.

생각과는 다르게 실제 객체는 Builder class 안이 아닌 Algorism class 안에서 만들어진다.

profile
개발자라고 우기는 노답 소년

0개의 댓글