Verstößt es gegen einen OOP-Principal, wenn eine Member-Funktion keine Klasseneigenschaften / Member-Variablen verwendet?
Nein.
OOP ist es egal, ob Ihre Mitgliedsfunktion Klasseneigenschaften oder Mitgliedsvariablen verwendet oder nicht verwendet. OOP kümmert sich um Polymorphismus und nicht um die Implementierung einer harten Codierung. Statische Funktionen haben ihre Verwendung, aber eine Funktion sollte nicht statisch sein, nur weil sie nicht vom Objektstatus abhängt. Wenn das dein Denken ist, aber beschuldige OOP nicht, weil diese Idee nicht von OOP kam.
Ist [es] schlechtes Design [um] Mitgliedsvariablen nicht zu verwenden?
Wenn Sie sich den Status nicht von Anruf zu Anruf merken müssen, gibt es keinen guten Grund, den Status zu verwenden.
Welches Prinzip des objektorientierten Designs verstößt es?
Keiner.
Wenn eine Mitgliedsfunktion die Mitgliedsvariable nicht verwendet, sollte diese Mitgliedsfunktion immer statisch gemacht werden?
Nein. Bei diesem Denken geht der Implikationspfeil in die falsche Richtung.
Eine statische Funktion kann nicht auf den Instanzstatus zugreifen
Wenn die Funktion nicht auf den Instanzstatus zugreifen muss, kann die Funktion statisch oder nicht statisch sein
Es liegt ganz bei Ihnen, die Funktion hier statisch zu machen. Aber es wird es eher wie ein globales, wenn Sie dies tun. Bevor Sie statisch werden, sollten Sie die Funktion in einer zustandslosen Klasse hosten. Es ist flexibler.
Ich habe hier ein OOP-Beispiel für eine Member-Funktion, die keine Klasseneigenschaften oder Member-Variablen verwendet.
Die Mitgliedsfunktion (und ihre zustandslose Klasse) :
#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.
};
Drei verschiedene Implementierungen:
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;
}
};
Ein Ort zum Speichern der Wahl der Implementierung:
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);
}
};
Ein Anwendungsbeispiel
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";
}
Ausgänge:
Called ConcreteStrategyAdd's execute()
Called ConcreteStrategySubstract's execute()
Called ConcreteStrategyMultiply's execute()
resultA: 7
resultB: -1
resultC: 12
Und das alles, ohne execute()
sich um den Zustand eines Objekts zu kümmern. Die Strategy
Klasse ist eigentlich staatenlos. Nur Staat ist in Context
. Staatenlose Objekte sind in OOP vollkommen in Ordnung.
Diesen Code haben Sie hier gefunden .