겨울팥죽 여름빙수
Published 2014. 4. 16. 10:54
c++ Builder 패턴 게임을 만들자/C++


1. 다수의 멤버변수

  보통 UI클래스나, 많은 정보를 가진 데이터 클래스(java의 bean객체 같은)의 경우, 많은 멤버 변수를 가진다. 이런 멤버 변수들을 생성자 파라미터로 초기화하면, 코드가 많이 복잡해 보일 수 있다. 예를 들어, 아래 클래스 처럼 new를 통해 파라미터로 값을 초기화하는 경우, 가독성이 많이 떨어진다(각각의 파라미터가 어떤 의미인지 알기 어렵다). 이런 문제를 해결하기 위해 get, set함수를 만들고 사용하기도 하는데 별로 만족 스럽지 못하다.


<code />
class Node { protected: vec2 m_position; vec2 m_draw_position; float m_width; float m_height; AlignType m_child_align_type; Margin m_margin; Padding m_padding; Color m_bg_color; AlignType m_resolution_type; bool m_is_draw_margin_padding; float m_scale; int m_ui_key; //------------------------------------------------------------------// //.... 기타 생성자 및 get, set함수들 } main() { //인자가 많아지면서, 보기 안 좋아짐. 각 파라미터가 무엇을 의미하는지 알 수 없음 new Node(10, 0, 10, ...) //가독성은 좋지만, 뭔가 만족스럽지 못함 Node* node = new Node(); node->setWidth(10); node->setHeight(10); node->setPosition(10); node->setScale(10); .... }


2. Builder 클래스

  이런 문제를 해결하기 위한 방법으로, Builder클래스를 따로 만드는 것이다. 아래 예를 보면, 어디선가 많이 본적이 있는 객체 생성방법일 것이다(안드로이드에서 Notification이나,  AlertDialog 등, 많은 클래스에서 사용). 


<code />
class ImageView : public Node { public: class Builder { friend class ImageView; private: // 선택적으로 초기화 해도 되는 멤버 vec2 m_position; //logical position vec2 m_draw_position; //real position of screen float m_width; float m_height; AlignType m_child_align_type; Margin m_margin; Padding m_padding; Color m_bg_color; AlignType m_resolution_type; //vbox and hbox children don't need this member bool m_is_draw_margin_padding; float m_scale; //반드시 초기화 돼야 하는 멤버 int m_ui_key; public: Builder(shared_ptr& parent, int ui_key) :m_width(0), m_height(0), m_scale(GLManager::getInstance()->jd_scale), m_child_align_type(NONE), m_position(0, 0), m_bg_color(1.0f, 0.452f, 0.834f, 1.0f), m_parent(parent), m_ui_key(ui_key), m_resolution_type(NONE), m_is_draw_margin_padding(true) {} ImageView* build() { return new ImageView(*this); } Builder& position(vec2 value) { m_position = value; return (*this);} Builder& drawPosition(vec2 value) { m_draw_position = value; return (*this);} Builder& width(float value) { m_width = value; return (*this);} Builder& height(float value) { m_height = value; return (*this);} Builder& childAlignType(AlignType value) { m_child_align_type = value; return (*this);} Builder& margin(Margin value) { m_margin = value; return (*this);} Builder& padding(Padding value) { m_padding = value; return (*this);} Builder& bgColor(Color value) { m_bg_color = value; return (*this);} Builder& resolutionType(AlignType value) { m_resolution_type = value; return (*this);} Builder& isDrawMarginPadding(bool value) { m_is_draw_margin_padding = value; return (*this);} Builder& scale(float value) { m_scale = value; return (*this);} }; public: ImageView(Builder& build) { m_position = build.m_position; m_draw_position = build.m_draw_position; m_width = build.m_width; m_height = build.m_height; m_child_align_type = build.m_child_align_type; m_margin = build.m_margin; m_padding = build.m_padding; m_bg_color = build.m_bg_color; m_resolution_type = build.m_resolution_type; m_is_draw_margin_padding = build.m_is_draw_margin_padding; m_scale = build.m_scale; m_parent = build.m_parent; m_ui_key = build.m_ui_key; } }; //사용 main() { ImageView* view = ImageView::Builder(m_root_anchor_pane, getUIKey()) .width(100) .height(100) .position(image_view_pos) .resolutionType(CENTER_MIDDLE) .build(); }


  - 장점 : 코드 가독성이 좋다(초기화하는 값이 어떤 것을 의미하는지 알기 쉽다).

  - 단점 : 객체 생성 비용이 2배 정도 든다. 때문에 매 프레임마다 자주 생성과 소멸을 반복하는 클래스에서는 사용하지 않는 것이 좋다.



'게임을 만들자 > C++' 카테고리의 다른 글

c++11 min, max 범위, 난수 생성  (1) 2020.04.07
c++ string tokenizer  (0) 2015.01.09
cJSON parsing error using window utf-8 txt file, Remove UTF-8 BOM  (0) 2015.01.08
c++ Easing code  (0) 2014.10.16
c++ const  (0) 2014.04.15
profile

겨울팥죽 여름빙수

@여름빙수

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!