- ベストアンサー
抽象クラスを作った際にインタフェースが増えすぎる
- 図形クラスのファクトリーパターンで、図形ごとのインタフェースと関数が増えすぎる問題が発生しています。
- 図形ごとに異なる初期値が必要であり、それぞれのインスタンスを生成するためのパラメータが異なる。
- 初期化のパラメータを抽象化することで、増えすぎるインタフェースを解決することができます。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> 図形が増えるたびに、そのインタフェースが増え そのためのファクトリーパターンでは? まずは #1 の方のとおり、使用するクラスを整理することですね。三角形・星型→多角形など。 それと、動作を enum ZUKEI のパラメータで変えている意味がわからないので、メソッド名を createRectangle, createCircle などにすべきでしょう。 他に例えば、長方形と楕円から大きさパラメータをくくりだして size(int width, int height) のように factory の状態を変化させればいいかもしれません。 例 class ShapeFactory { int x, y, centerx, centery, width, height; public: Shape *createRectangle(); Shape *createEllipse(); Shape *createCircle(int radius); ... void size(int width, int height); void pos(int x, int y); void center(int x, int y); ... }; 使用例 Shape *rect = factory.pos(10,10).size(100,50).createRectangle(); Shape *ellipse = factory.center(50,50).size(50,30).createEllipse(); Shape *circle = factory.center(50,50).createCircle(50);
その他の回答 (1)
- hitomura
- ベストアンサー率48% (325/664)
> Zukei* sankaku = zukeiFactory.create(SHIKAKU, x, y, width, height); > Zukei* shikaku = zukeiFactory.create(EN, centerX, centerY, radius); 変数名と作っている図形が異なっている件 ……はおいといて、こんな感じかなぁ。 enum ParameterType { POSITION, RECT_SIZE, RADIUS, POSITIONS, // ... } class Parameter { public: Parameter(ParameterType type) : type_(type) {}; virtual ~Parameter() = 0; ParameterType getType() const {return type_;}; private: ParameterType type_; }; class Position : public Parameter { public: Position(int x, int y) : Parameter(POSITION), x_(x), y_(y) {}; ~Position() {}; int getX() const {return x_;}; int getY() const {return y_;}; private: int x_; int y_; }; // 以下、上記と同様に矩形サイズ、半径、点列(三角形とか星型で使うはず)クラスを作成 // 点列は個数を固定するより std::vector<Position> を使ったほうがいいかも struct ParameterSercher { ParameterSercher() ParameterSercher(ParameterType type) : type_(type) {}; bool operator()(const Parameter* param) { return param->getType() == type_; } private: ParameterType type_; } Zukei* ZukeiFactory::create(int zukeiId, const vector<Parameter*>& params) { switch(zukeiId) { case SHIKAKU: vector<Parameter>::const_iterator i_pos = find_if(params.begin(), params.end(), ParameterSercher(POSITION)); vector<Parameter>::const_iterator i_rect_size = find_if(params.begin(), params.end(), ParameterSercher(RECT_SIZE)); if (i_pos == params.end()) || (i_rect_size == params.end()) return NULL; int x = dynamic_cast<Position*>(*i_pos)->getX(); int y = dynamic_cast<Position*>(*i_pos)->getY(); int width = dynamic_cast<RectSize*>(*i_rect_size)->getWidth(); int height = dynamic_cast<RectSize*>(*i_rect_size)->getHeight(); return new ShikakuZukei(x, y, width, height); case EN: // 以下、上記と同様 } } Position* sankaku_pos = new Position(x, y); RectSize* sankaku_rect = new RectSize(width, height); vaector<Parameter*> params; params.push_back(sankaku_pos); params.push_back(sankaku_rect); Zukei* sankaku = zukeiFactory.create(SHIKAKU, params);