일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- topic
- 프로그래밍
- 반복문
- 오늘도 우라라 공략
- 오늘도 우라라 펫 공략
- 기초
- 환경설정
- 그랑사가
- mariaDB
- Subscribe
- C언어
- 마리아 DB
- mysql
- MSG
- LeetCode
- 오늘도 우라라 펫
- publish
- 오늘도 우라라
- Linux
- 리눅스
- while
- C++
- 토픽
- 우분투
- JungOl
- ros
- 등차수열
- 데이터 베이스
- install opencv-4.4.0 on ubuntu 22.04
- ubuntu
- Today
- Total
하루의 쉼터
[CreationalPatterns] Builder Pattern 본문
| OutLine. 점층적 생성자 패턴 (Telescoping Constructor Pattern)
│─ 특징
│─ 장점
│─ 단점
│─ Class Diagram
│─ 구성
│─ 코드 With.C++
│─ Result(후기)
└─ Github
복잡한 생성 과정의 객체를 생성과 구현을 분리하고 동일한 로직의 생성을 거쳐 결과를 만들어냄.
특징
- 객체 생성 과정을 인터페이스 클래스와 구현 클래스로 분리하여 유연함.
- 객체 생성 과정을 캡슐화하여 생성하는 방식을 추상화함.
- 객체 생성 과정에서 필요 매개변수를 검사하고 생성함.
장점
- 인터페이스를 통하여 재구현하는 방식으로 동일한 로직에 다른 객체 생성이 가능
- 유연하여 재사용성이 높아 유지보수에 유리
- 객체 생성 과정에서 인터페이스를 활용하여 오류 방지
- 복잡한 생성 구조를 분리하여 가독성이 좋음.
단점
- 객체 생성이 복잡하지 않은 경우 코드가 지저분해짐.
- 관리할 클래스가 많아짐.
Class Diagram
구성
- Procuct (생성될 객체)
- Builder 패턴에서 생성 될 객체
- Concrete Builder를 통하여 생성됨.
- Builder (빌더 - 구성해야할 인터페이스)
- 인터페이스 클래스 ( 추상클래스 )
- Concrete Builder (구현 빌더 - 구현 클래스)
- 구현 클래스
- 생성 시 필요한 로직을 구현
- Director (감독, 관리)
- Product 객체를 관리하며, 인터페이스를 받아 생성하고 Concrete Builder를 유연하게 선택 가능
- 인터페이스를 사용하여 객체 생성 순서를 결정
- 인터페이스를 통하여 여러 클래스를 동적으로 생성 변경 가능.
- 처음 이 패턴을 봤을 때는 Concrete Builder에서 생성한 로봇을 반환하면 굳이 Director 클래스를 사용하지 않아도 되지 않나 하였으나, Director 클래스를 통해 생성 과정이나 방법을 결정할 수 있고, Concrete Builder에 변경이 일어나도 Client(사용자) 코드는 변경이 최소화 되는 이점이 있음.
코드 - With. C++
Product - Robot.hpp
#pragma once
#include<iostream>
// builder
/**
* @brief Robot Builder
*/
class Robot{
private:
std::string m_model_name;
float m_max_vel;
float m_max_angle;
float m_min_vel;
float m_min_angle;
public:
Robot();
void fn_set_model_name(std::string model_name);
void fn_set_max_vel(float max_vel);
void fn_set_max_angle(float max_angle);
void fn_set_min_vel(float min_vel);
void fn_set_min_angle(float min_angle);
virtual ~Robot();
void fn_print_all();
};
Product - Robot.cpp
#include "Robot.hpp"
Robot::Robot() : m_model_name("Defualt"), m_max_vel(0),m_max_angle(0),m_min_vel(0),m_min_angle(0){
}
void Robot::fn_set_model_name(std::string model_name){
m_model_name = model_name;
}
void Robot::fn_set_max_vel(float max_vel){
m_max_vel = max_vel;
}
void Robot::fn_set_max_angle(float max_angle){
m_max_angle = max_angle;
}
void Robot::fn_set_min_vel(float min_vel){
m_min_vel = min_vel;
}
void Robot::fn_set_min_angle(float min_angle){
m_min_angle = min_angle;
}
Robot::~Robot() {
}
void Robot::fn_print_all() {
std::cout << "model_name : " << m_model_name << " max_vel : " << m_max_vel << " max_angle : " << m_max_angle << " min_vel : " << m_min_vel << " min_angle : " << m_min_angle << std::endl;
}
Builder - IRobotBuilder.hpp
#pragma once
class IRobotBuilder {
public:
virtual void fn_set_model_name() = 0;
virtual void fn_set_max_vel() = 0;
virtual void fn_set_max_angle() = 0;
virtual void fn_set_min_vel() = 0;
virtual void fn_set_min_angle() = 0;
virtual Robot* fn_get_robot() = 0;
};
Concrete Builder - TurtlebotConcreteBuilder.hpp
#pragma once
#include"Robot.hpp"
#include"IRobotBuilder.hpp"
class TurtlebotConcreteBuilder : public IRobotBuilder {
public :
TurtlebotConcreteBuilder();
void fn_set_model_name();
void fn_set_max_vel();
void fn_set_max_angle();
void fn_set_min_vel();
void fn_set_min_angle();
Robot* fn_get_robot();
private :
Robot* robot;
};
Concrete Builder - TurtlebotConcreteBuilder.cpp
#include "TurtlebotConcreteBuilder.hpp"
TurtlebotConcreteBuilder::TurtlebotConcreteBuilder(){
robot = new Robot();
}
void TurtlebotConcreteBuilder::fn_set_model_name(){
robot->fn_set_model_name("Turtlebot");
}
void TurtlebotConcreteBuilder::fn_set_max_vel(){
robot->fn_set_max_vel(10);
}
void TurtlebotConcreteBuilder::fn_set_max_angle(){
robot->fn_set_max_angle(20);
}
void TurtlebotConcreteBuilder::fn_set_min_vel(){
robot->fn_set_min_vel(3);
}
void TurtlebotConcreteBuilder::fn_set_min_angle(){
robot->fn_set_min_angle(10);
}
Robot* TurtlebotConcreteBuilder::fn_get_robot(){
return robot;
}
Concrete Builder - ChangunbotConcreteBuilder.hpp
#pragma once
#include"Robot.hpp"
#include"IRobotBuilder.hpp"
class ChangunbotConcreteBuilder : public IRobotBuilder {
public:
ChangunbotConcreteBuilder();
void fn_set_model_name();
void fn_set_max_vel();
void fn_set_max_angle();
void fn_set_min_vel();
void fn_set_min_angle();
Robot* fn_get_robot();
private :
Robot* robot;
};
Concrete Builder - ChangunbotConcreteBuilder.cpp
#include "ChangunbotConcreteBuilder.hpp"
ChangunbotConcreteBuilder::ChangunbotConcreteBuilder() {
robot = new Robot();
}
void ChangunbotConcreteBuilder::fn_set_model_name(){
robot->fn_set_model_name("Changunbot");
}
void ChangunbotConcreteBuilder::fn_set_max_vel(){
robot->fn_set_max_vel(50);
}
void ChangunbotConcreteBuilder::fn_set_max_angle(){
robot->fn_set_max_angle(30);
}
void ChangunbotConcreteBuilder::fn_set_min_vel(){
robot->fn_set_min_vel(2);
}
void ChangunbotConcreteBuilder::fn_set_min_angle(){
robot->fn_set_min_angle(5);
}
Robot* ChangunbotConcreteBuilder::fn_get_robot(){
return robot;
}
Director - RobotDirector.hpp
#pragma once
#include"Robot.hpp"
#include"IRobotBuilder.hpp"
class RobotDirector{
public :
void fn_set_robot_builder(IRobotBuilder* robot_builder);
Robot* fn_build();
private :
IRobotBuilder* m_robot_builder;
};
Director - RobotDirector.cpp
#include "RobotDirector.hpp"
void RobotDirector::fn_set_robot_builder(IRobotBuilder* robot_builder){
m_robot_builder = robot_builder;
}
Robot* RobotDirector::fn_build()
{
m_robot_builder->fn_set_model_name();
m_robot_builder->fn_set_max_vel();
m_robot_builder->fn_set_max_angle();
m_robot_builder->fn_set_min_vel();
m_robot_builder->fn_set_min_angle();
return m_robot_builder->fn_get_robot();
}
main.cpp
#include "TurtlebotConcreteBuilder.hpp"
#include "ChangunbotConcreteBuilder.hpp"
#include "Robot.hpp"
#include "RobotDirector.hpp"
int main() {
RobotDirector robot_director;
RobotDirector changunbot_director;
TurtlebotConcreteBuilder turlebot;
ChangunbotConcreteBuilder changunbot;
robot_director.fn_set_robot_builder(&turlebot);
changunbot_director.fn_set_robot_builder(&changunbot);
Robot* robot_turlebot = robot_director.fn_build();
Robot* robot_changunbot = changunbot_director.fn_build();
robot_turlebot->fn_print_all();
robot_changunbot->fn_print_all();
}
Result
클래스 구성도 좋고 인터페이스를 활용하여 유연성도 좋으며 같은 로직으로 다른 객체를 생성해낼 수 있어서 유용함.
다만 관리할 클래스가 많아지므로 생성이 복잡하지 않은 구조에서는 다른 생성 패턴을 쓰는게 유리해보임.
GitHub
https://github.com/Anchangun/cpp_study/tree/DesinPattern/DesinPattern/BuilderPattern
'프로그래밍 > DesinPattern' 카테고리의 다른 글
[CreationalPatterns] Telescoping Constructor Pattern - 점층적 생성자 패턴 (0) | 2023.04.13 |
---|