在作曲的情况下访问'inner'类
Access to 'inner' classes in case of composition
我将某些功能封装在类中,然后在另一个类中使用。我想这叫做构图。
class DoesSomething01
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
private:
DoesSomething01 *m_doesSomething01;
DoesSomething02 *m_doesSomething02;
};
如果我现在有一个"知道"ClassA
的ClassB
,并且必须使用/执行DoesSomething01
和/或DoesSomething02
类的functionality01
和/或functionality02
,我看到两种可能性:
ClassA
添加这样的方法,使ClassB
可以直接访问DoesSomething01
和/或DoesSomething02
:
DoesSomething01 *getDoesSomething01() { return *m_doesSomething01; }
DoesSomething02 *getDoesSomething02() { return *m_doesSomething02; }
ClassB
可以这样做:
m_classA->getDoesSomething01()->functionality01();
b)为ClassA
添加(在本例中为四个)方法,将方法调用转发给DoesSomething01
和DoesSomething02
,如下所示:
void doesSomething01Functionality01() { m_doesSomething01->functionality01(); }
void doesSomething01Functionality02() { m_doesSomething01->functionality02(); }
void doesSomething02Functionality01() { m_doesSomething02->functionality01(); }
void doesSomething02Functionality02() { m_doesSomething02->functionality02(); }
哪个选项更好,为什么?
每个选项的优缺点是什么?
第一个选项可以被认为是代码气味。根据Robert C. Martin的"Clean Code",这是"传递式导航",应该避免。引用作者:
一般来说,我们不希望单个模块知道太多关于它的信息合作者。更具体地说,如果A与B合作,B与C协作,我们不希望使用A的模块知道C。(例如,我们不希望a.getB(). getc (). dosomething ();)
第二个选项看起来更好。它是立面图案的经典使用。而且它更好,因为它隐藏了DoesSomthing01
和DoesSomthing02
类的其他功能。这样你就得到了简化的视图这比第一个选项更容易使用。
class DoesSomething
{
public:
virtual void functionality01() = 0;
virtual void functionality02() = 0;
}
class DoesSomething01 : DoesSomething
{
public:
DoesSomething01();
void functionality01();
void functionality02();
};
class DoesSomething02 : DoesSomething
{
public:
DoesSomething02();
void functionality01();
void functionality02();
};
class ClassA
{
public:
ClassA();
DoesSomething* doesSomething(); // Getter
void doesSomething(DoesSomething* newDoesSomething); // Setter
// ...
private:
DoesSomething *m_doesSomething;
};
那么你只需要两个方法而不是四个:
void doesFunctionality01() { m_doesSomething->functionality01(); }
void doesFunctionality02() { m_doesSomething->functionality02(); }
第一个场景违反了得墨忒耳定律,该定律规定一个类只能与它的直接好友通信。基本上,第一种方法的问题是,内部类DoSomething01和DoSomething02的任何变化都会触发类a和类B的变化,因为两个类现在都直接依赖于这些内部类。
第二个选项更好,因为它从内部类封装了类B,但这个解决方案的一个副作用是,现在类a有很多方法,除了委托给它的内部类之外,没有什么特别的功能。这很好,但是想象一下,如果DoSomething01有一个内部类DoSomething03,而类B需要在不直接知道它的情况下访问它的功能,那么类A将需要另一个方法来委托给DoSomething01,而DoSomething01又会委托给DoSomething03。在这种情况下,我认为最好让类B直接知道DoSomething01,否则类A将有一个巨大的接口,只是委托给它的内部类。
如果有许多类和/或许多方法需要调用,那么发明是有意义的抽象父类形式的接口:
class SomeInterface
{
public:
SomeInterface(){}
virtual void functionally01() = 0;
virtual void functionally02() = 0;
}
DoesSomthing01和其他类将继承这个类:
class DoesSomthing01 : public SomeInterface
并实现方法
如果将一个键与这样一个类的实例化相关联是有意义的
你可以将这些对象存储在类a中,例如使用map(这里是I使用整数作为键):
class ClassA
{
private:
std::map<int, SomeInterface*> m_Interfaces;
public:
SomeInterface* getInterface(const int key)
{
std::map<int, SomeInterface*>::iterator it(m_Interfaces.find(key));
if (it != m_Interfaces.end())
return it->second;
else
return NULL;
}
};
可以从ClassB中访问它们
int somekey = ...;
SomeInterface *myInter = m_classA->getInterface(somekey);
if (myInter)
myInter->functionally01();
这样你只有一个独立的访问方法(getInterface())对象的个数
为了使用键对方法的访问进行编码,您可以创建一个map,将键映射到闭包或简单的switch语句上:在SomeInterface:
public:
void executeMethod(const int key)
{
switch(key)
{
case 1: functionally01(); break;
case 2: functionally01(); break;
default:
// error
}
int methodKey = ...;
int objectKey = ...;
SomeInterface *myInter = m_classA->getInterface(objectKey);
if (myInter)
myInter->executeMethod(methodKey);
看起来是一个很好的中介模式。
这个模式管理他拥有的两个对象之间的通信
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 用于访问容器<T>数据成员的正确 API
- 访问者访问变体并返回不同类型时出错
- 尝试通过多个向量访问变量时,向量下标超出范围
- 无法访问嵌套类.类的使用无效
- 写入位置0x0000000C时发生访问冲突
- 我们可以访问一个不存在的联盟的成员吗
- C++从另一个类访问公共静态向量的正确方法是什么
- 我的简单if-else语句是如何无法访问的代码
- 从C++dll访问C#中的一行主要参数
- 概念TS检查忽略私有访问修饰符
- 访问被拒绝后,c++中的故障保护代码
- 在c++中访问int到类对象的映射时出错
- 我想访问std::unique_ptr中的一个特定元素
- 为什么示例代码访问IUnknown中已删除的内存
- 如何从C 中的Inner Union访问类成员
- 在作曲的情况下访问'inner'类
- C++多维地图:如何访问'inner'地图?