Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我是否应该尝试在第三方库中修复一个可能很糟糕的设计决策?_C++_Design Patterns - Fatal编程技术网

C++ 我是否应该尝试在第三方库中修复一个可能很糟糕的设计决策?

C++ 我是否应该尝试在第三方库中修复一个可能很糟糕的设计决策?,c++,design-patterns,C++,Design Patterns,我的项目涉及Qt plus和未命名的第三方物理模拟库。物理图书馆的工作方式是物理实体不能创造自我;“世界”必须实例化它们,以便可以立即将它们添加到世界中 我的项目在这些物理体周围创建了一个包装器,以添加一些额外的功能,但由于它存储了这些物理体,因此也无法实例化。第一个问题是,允许这些机构独立存在是否更有意义?我感到尴尬的是,我必须将对世界的引用传递给对象,这样才能创建它,而对我来说,将对象传递给世界更有意义 为了解决这个问题,我可以推迟第三方主体的创建,直到它被添加到我的世界包装中。但这意味着我

我的项目涉及Qt plus和未命名的第三方物理模拟库。物理图书馆的工作方式是物理实体不能创造自我;“世界”必须实例化它们,以便可以立即将它们添加到世界中

我的项目在这些物理体周围创建了一个包装器,以添加一些额外的功能,但由于它存储了这些物理体,因此也无法实例化。第一个问题是,允许这些机构独立存在是否更有意义?我感到尴尬的是,我必须将对世界的引用传递给对象,这样才能创建它,而对我来说,将对象传递给世界更有意义

为了解决这个问题,我可以推迟第三方主体的创建,直到它被添加到我的世界包装中。但这意味着我的世界包装器将负责正确初始化身体。这也意味着,在对象添加到世界之前,我无法真正访问对象的任何属性,因为它们都依赖于正在初始化的第三方主体。。。除非我复制所有数据,然后在添加数据时将其传递给库

这值得付出努力,还是我应该继续传递指向我的世界包装器的指针,以便创建我的身体包装器


我提到Qt,因为Qt图形框架的工作方式是,您可以随时创建QGraphicsItems,它们将独立存在,但只有将它们添加到场景中,它们才会可见。这里的类比是GraphicsItem==Body,Scene==World。

为了真正有效,facade模式(包装器)必须对facade的用户隐藏实现的底层细节。这意味着使用数据传输对象来保存数据。Facade的实现可能会很麻烦,但它们使您能够在不影响最终用户的情况下更改底层实现

sudo代码:

Rock rock = new Rock(100); //simple data container for now.

PhysicsFacade f = new PhysicsFacade(); //internally creates world.

f.DoSomething(rock); //internally rock's data used by world to create an equivalent    object which is attached to the rock data container for future use.

为了真正有效,门面模式(包装器)必须对门面用户隐藏实现的底层细节。这意味着使用数据传输对象来保存数据。Facade的实现可能会很麻烦,但它们使您能够在不影响最终用户的情况下更改底层实现

sudo代码:

Rock rock = new Rock(100); //simple data container for now.

PhysicsFacade f = new PhysicsFacade(); //internally creates world.

f.DoSomething(rock); //internally rock's data used by world to create an equivalent    object which is attached to the rock data container for future use.
我所有的getter和setter基本上都需要检查“主体已经初始化了吗?”

如果你使用QT,我假设你使用C++。< /P> <>我不知道Qt,我不知道为什么你想改变现有的机制,但是无论如何,C++中有一件事情是可以做的,那就是对你有用,就是重载<代码> -> /Cord>运算符来访问你的对象。当有人调用

->
操作符时,如果对象尚未实例化,该操作符也可以及时创建对象,例如:

World& getWorld();

class Body;

class MyWrapper
{
  Body* m_body;

public:

  MyWrapper() : m_body(0) {}

  Body* operator->()
  {
    if (!m_body)
    {
      m_body = new Body(getWorld());
    }
    return m_body;
  }

  ... etc ...
};

编辑

“改变现有机制”是什么意思?物理图书馆布置的那个?我想我提到了我的理由

用你的解决方案。。。getWorld()做什么?这是一个全局函数吗?若世界在全局空间中浮动,那个么实际上并没有问题,我可以在实例化MyWrapper的同时实例化主体

是的,它返回对世界的引用,这是在物理库中创建实体所需的。这是一个例子,我不知道你从哪里得到你的世界参考,也不知道什么时候

但是,如果在使用->操作符时世界仍然不存在怎么办?我不确定这能解决什么问题。更不用说这种或那种方式,你仍然在把世界传递给身体

如果调用得太早,
getWorld
可能会抛出异常。不管怎么说,这本应该给你买的是:

  • 创建
    MyWrapper
    实例的能力,无需世界引用,可能在创建世界之前

  • 当客户端试图访问实体的任何属性或方法时,能够及时创建实体实例

->操作符是客户端用来获取您正在包装的物理体的:就像一个“智能指针”

如果您使用一些伪代码来说明您的问题,可能更容易理解和/或为您的问题提出解决方案

更不用说这种或那种方式,你仍然在把世界传递给身体

您说过这是底层库的要求。当您说“我应该尝试修复吗?”时,我以为您的意思是“我应该在包装器中实现不同的API,并将现有API隐藏在我的私有实现中吗?”我没有想到您可能会尝试更改(而不仅仅是包装)现有实现

我所有的getter和setter基本上都需要检查“主体已经初始化了吗?”

如果你使用QT,我假设你使用C++。< /P> <>我不知道Qt,我不知道为什么你想改变现有的机制,但是无论如何,C++中有一件事情是可以做的,那就是对你有用,就是重载<代码> -> /Cord>运算符来访问你的对象。当有人调用

->
操作符时,如果对象尚未实例化,该操作符也可以及时创建对象,例如:

World& getWorld();

class Body;

class MyWrapper
{
  Body* m_body;

public:

  MyWrapper() : m_body(0) {}

  Body* operator->()
  {
    if (!m_body)
    {
      m_body = new Body(getWorld());
    }
    return m_body;
  }

  ... etc ...
};

编辑

“改变现有机制”是什么意思?物理图书馆布置的那个?我想我提到了我的理由

用你的解决方案。。。getWorld()做什么?这是一个全局函数吗?若世界在全局空间中浮动,那个么实际上并没有问题,我可以在实例化MyWrapper的同时实例化主体

是的,它返回对世界的引用,这是在物理库中创建实体所需的。这是一个例子,我不知道