我试图理解为什么单身人士不满意。
假设我有单身MyClass:
class MyClass
{
public:
void doSomething();
static MyClass* getInstance();
private:
int whatever;
static MyClass* myClass;
MyClass();
};
我有一个引用它的类:
void A::B()
{
...
MyClass::getInstance()->doSomething();
}
我读到的是现在A类依赖于MyClass。测试类A有效地意味着同时测试MyClass。任何地方的任何人都可以同时修改我们的MyClass,因此A :: B()的结果是不可预测的。
但为什么全球可访问性是其原因?如果我们有聚合怎么办?如果A类有一个指针或对MyClass对象的引用,而其他类也有指向或引用同一个对象,该怎么办?
class A
{
public:
void B();
private:
MyClass* myClass;
};
void A::B()
{
...
myClass->doSomething();
}
你能不能遇到同样的问题,其他一些类同时修改同一个myClass对象,因此A :: B()依赖于它?我想问题是,在多个地方引用相同的东西是不是几乎像“全球国家”?
(我知道此问题之前已经发布过,但我认为其他人没有具体询问为什么对同一个对象的多个引用更好。)
答案 0 :(得分:1)
“任何地方的任何人都可以同时修改我们的MyClass”
这只能在某种多线程或多进程环境中实现。如果关注的话,你的第二个例子似乎并没有好转。
Globals - 或称为Singletons作为您的称呼 - 不建议在多线程环境中使用,因为可能是并发访问,这就是您所说的。为了避免并发问题,您需要处理同步机制 - 并不总是那么容易。
即使没有多线程,Globals也会使代码难以管理,调试和控制,而不仅仅是琐碎的系统。
通常,“聚合”不是“单身”的替代品。 singleton的替代方案是多个实例,每个实例专用于特定线程,或者是特定类或方法的本地实例 - 也许是“聚合”的意思 - 从而避免并发和控制/代码管理问题。
“汇总”“委托”或“对象组合”(在此上下文中或多或少的同义词)通常被视为替代方案继承:而不是从基类继承功能,通常更需要设计一个完全独立的类来执行必要的功能,并由调用类引用和控制 - “黑盒子”概念
继承的问题之一是它倾向于强制派生类处理来自基类的实现和行为,这在派生类中可能是不合适的。它总是强制将实现细节暴露给派生类,从而违反封装。理想情况下,一个设计良好的类层次结构将避免这个问题,但如果你正在处理类Cat(动物),类Dog(Animal)等教科书定义之外的任何事情,设计这样的类层次结构通常不是一件简单的事。