Nó có vi phạm bất kỳ hiệu trưởng OOP nào không nếu hàm thành viên không sử dụng bất kỳ thuộc tính lớp / biến thành viên nào?
Không.
OOP không quan tâm nếu hàm thành viên của bạn sử dụng hoặc không sử dụng các thuộc tính lớp hoặc biến thành viên. OOP quan tâm đến đa hình và không thực hiện mã hóa cứng. Các hàm tĩnh có công dụng của chúng nhưng một hàm không nên tĩnh đơn giản vì nó không phụ thuộc vào trạng thái đối tượng. Nếu đó là suy nghĩ của bạn tốt, nhưng đừng đổ lỗi cho OOP vì ý tưởng đó không đến từ OOP.
Là [nó] thiết kế xấu [không] sử dụng các biến thành viên?
Nếu bạn không cần phải nhớ trạng thái từ cuộc gọi đến cuộc gọi thì không có lý do chính đáng để sử dụng trạng thái.
Nguyên tắc nào của thiết kế hướng đối tượng [không] nó vi phạm?
Không ai.
Nếu một hàm thành viên không sử dụng biến thành viên thì hàm thành viên đó sẽ luôn luôn được tạo thành tĩnh?
Không. Suy nghĩ này có mũi tên hàm ý đi sai hướng.
Làm cho chức năng tĩnh ở đây là hoàn toàn tùy thuộc vào bạn. Nhưng nó sẽ làm cho nó giống như một toàn cầu hơn nếu bạn làm. Trước khi đi tĩnh hãy xem xét việc lưu trữ hàm trong một lớp không trạng thái. Nó linh hoạt hơn.
Tôi có ở đây một ví dụ OOP của hàm thành viên không sử dụng các thuộc tính lớp hoặc biến thành viên.
Hàm thành viên (và đó là lớp không trạng thái) :
#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.
};
Ba cách thực hiện khác nhau:
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;
}
};
Một nơi để lưu trữ các lựa chọn thực hiện:
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);
}
};
Một ví dụ về việc sử dụng
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";
}
Đầu ra:
Called ConcreteStrategyAdd's execute()
Called ConcreteStrategySubstract's execute()
Called ConcreteStrategyMultiply's execute()
resultA: 7
resultB: -1
resultC: 12
Và tất cả mà không execute()
quan tâm đến trạng thái của bất kỳ đối tượng. Các Strategy
lớp thực sự là quốc tịch. Chỉ có nhà nước là trong Context
. Các đối tượng không trạng thái là hoàn toàn tốt trong OOP.
Tìm thấy mã này ở đây .