나만 쓰는 코드이긴 한데 프로젝트가 커질수도 있어서 디자인패턴 적용해서 관리해보려 하거든
생애 처음으로 팩토리 디자인패턴으로 짜봤는데
나중에 새로운 클래스 만들때마다 신경써야할게 좀 많은거같아서..
이상한부분이나 개선할부분좀 알려줘 형들ㅅ
스압ㅈㅅ
스토리:
로봇 모션플래닝 알고리즘을 optimization기법으로 구현하는중인데 다양한 cost 종류가 필요함 (smoothness, collision avoidance 등등)
팩토리를 통해서 "Smoothness"를 인자로 주면 new SmoothnessCost() 클래스인스턴스를 리턴하는 코드를 만들고싶음
프로젝트 구조:
include/
cost.h (base class 정의)
smoothness_cost.h (derived class 정의)
cost_factory.h (factory 정의)
src/
cost.cpp
smoothness_cost.cpp
cost_factory.cpp
코드 구조:
cost.h는 베이스클래스를 정의함class Cost{ ... };
<!--EndFragment-->그리고 derived class를 편하게 만들고자 정의한것은
#define COST_DERIVED_CLASS_DECL(type) \friend class CostFactory; \
public: virtual inline std::string getDescription() { return getDescription_(); } \private: static inline std::string getDescription_() { return std::string(#type) + std::string("Cost"); }
내가 원하는 cost 클래스를 만들때는 (예를들어 smoothness_cost.h)
바로 위에서 정의한거 한문장 넣고 시작해야함
<!--StartFragment-->class SmoothnessCost : public Cost{COST_DERIVED_CLASS_DECL(Smoothness)
...};<!--EndFragment-->
이제 팩토리에서 클래스 인스턴스를 만드는데 cost_factory.h 에는
<!--StartFragment-->class CostFactory { public: static Cost* newCost(const std::string& name, double weight); };cost_factory.cpp에선 derived class의 description과, 인풋으로 들어온 name (std::string 타입임)하고 비교해서 맞으면 그 클래스 만들어서 리턴
#define COST_DERIVED_CLASS_FACTORY(type) \
{ \
if (type##Cost::getDescription_() == name) return new type##Cost(); \
}
derived class 들어있는 헤더를 먼저 인클루드해야함
#include <smoothness_cost.h><!--EndFragment-->그리고 팩토리에
<!--StartFragment-->Cost* CostFactory::newCost(const std::string& name){COST_DERIVED_CLASS_FACTORY(Smoothness)
return 0;}<!--EndFragment-->
새로운 derived class추가할때:
예를들어 CollisionCost라는 클래스를 만든다 치면 내가 해야할건
1. collision_cost.h 에서 COST_DERIVED_CLASS_DECL(Collision) 이걸 클래스 시작할때 써야함
2. cost_factory.cpp 에서 맨위에다가 collision_cost.h를 인클루드해야함
3. cost_factory.cpp의 CostFactory::newCost 함수에다가 COST_DERIVED_CLASS_FACTORY(Collision) 문장을 추가해야함
새 클래스 만들려면 3가지를 따로따로 신경써줘야하니 좀 꺼림칙한데..
디자인패턴 처음 짜본 초짜한테 조언부탁해 형들
UML이 있으면 좋을텐뎅 ㅜ
코드 그림으로 변환하는건가보네? 미안 난 그런 기술이 없어서 ㅠㅠ