メンバー関数がクラスプロパティ/メンバー変数を使用しない場合、OOPプリンシパルに違反しますか?
番号。
OOPは、メンバー関数がクラスプロパティまたはメンバー変数を使用するかどうかを気にしません。OOPはポリモーフィズムに注意し、ハードコーディングの実装には注意しません。静的関数には用途がありますが、関数はオブジェクトの状態に依存しないという理由だけで静的であってはなりません。それがあなたの考えで良いのであれば、その考えはOOPから来たものではないので、OOPのせいにしないでください。
悪い設計はメンバー変数を利用する[しない]でしょうか?
呼び出しごとに状態を記憶する必要がない場合は、状態を使用する十分な理由はありません。
オブジェクト指向設計のどの原則に違反しますか?
無し。
メンバー関数がメンバー変数を使用しない場合、そのメンバー関数は常に静的にする必要がありますか?
いいえ。この考え方には、間違った方向に進むという意味合いの矢があります。
ここで関数を静的にするかどうかは完全にあなた次第です。しかし、そうすることで、よりグローバルな雰囲気になります。静的になる前に、関数をステートレスクラスでホストすることを検討してください。より柔軟です。
クラスプロパティまたはメンバー変数を使用しないメンバー関数のOOPの例を示します。
メンバー関数(およびステートレスクラス):
#include <iostream>
class Strategy
{
public:
virtual int execute (int a, int b) = 0; // execute() is a so-called pure virtual
// function. As a consequence, Strategy
// is a so-called abstract class.
};
3つの異なる実装:
class ConcreteStrategyAdd:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategyAdd's execute()\n";
return a + b;
}
};
class ConcreteStrategySubstract:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategySubstract's execute()\n";
return a - b;
}
};
class ConcreteStrategyMultiply:public Strategy
{
public:
int execute(int a, int b)
{
std::cout << "Called ConcreteStrategyMultiply's execute()\n";
return a * b;
}
};
実装の選択を保存する場所:
class Context
{
private:
Strategy* pStrategy;
public:
Context (Strategy& strategy)
: pStrategy(&strategy)
{
}
void SetStrategy(Strategy& strategy)
{
pStrategy = &strategy;
}
int executeStrategy(int a, int b)
{
return pStrategy->execute(a,b);
}
};
使用例
int main()
{
ConcreteStrategyAdd concreteStrategyAdd;
ConcreteStrategySubstract concreteStrategySubstract;
ConcreteStrategyMultiply concreteStrategyMultiply;
Context context(concreteStrategyAdd);
int resultA = context.executeStrategy(3,4);
context.SetStrategy(concreteStrategySubstract);
int resultB = context.executeStrategy(3,4);
context.SetStrategy(concreteStrategyMultiply);
int resultC = context.executeStrategy(3,4);
std::cout << "\nresultA: " << resultA
<< "\nresultB: " << resultB
<< "\nresultC: " << resultC
<< "\n";
}
出力:
Called ConcreteStrategyAdd's execute()
Called ConcreteStrategySubstract's execute()
Called ConcreteStrategyMultiply's execute()
resultA: 7
resultB: -1
resultC: 12
そして、すべてのexecute()
オブジェクトの状態を気にすることなく。Strategy
クラスは、実際にステートレスです。状態のみContext
です。ステートレスオブジェクトは、OOPでは完全に問題ありません。
このコードはここにあります。