原型模式导致"actual object"和"prototype"之间的代码重复
Prototype Pattern causes code repetition between "actual object" and "prototype"
在将原型模式中采用后,它宜人提高了我的代码的可维护性。
但是,我开始担心实际对象变得更加细节化时,
我倾向于编码对应的原型更像是实际对象的副本。
(代码中的通知#v.2)
class Prototype{ //aka. "fake object"
public: Vec3 position;
//bool isShootable; //(#v.2) //#X
//float delayBetweenShoot; //(#v.2)
//float hp; //(#v.2)
};
class Actual{ //aka. "actual object"
public: PhysicObject* rigidBody=nullptr;
//bool isShootable; //(#v.2) //#X
//float delayBetweenShoot; //(#v.2)
//float hp; //(#v.2)
};
int main(){ // simplify
Prototype prototype;
prototype.position = Vec3(1,2,3);
//^ end prototype creation
//v these lines are inside a function, but it simply works like this
PhysicObject* phy=new PhysicObject(prototype.position);
Actual actual;
actual.rigidBody=phy;
//actual.isShootable =prototype.isShootable; //(#v.2) #Y
//actual.delayBetweenShoot=prototype.delayBetweenShoot; //(#v.2)
//actual.hp =prototype.hp; //(#v.2)
gameLogic.add(actual); //roughly speaking
}
有两个不良信号(#v.2): -
1. Prototype
中的重复代码与Actual
(#X)
2.乏味的田野复制。(#Y)
因此,我认为有些事情开始出问题。
这种模式自然会引起新的可维护性问题。
在实际情况下,actual2
包含另一个actual1
。
要采用原型模式,我在另一个相应的prototype1
中使用相应的prototype2
: -
class Actual1{
//... some fields e.g. A1 a1; A2 a2; A3 a3;
};
class Actual2{
//... some other field e.g. B1 B2 B3
Actual1 actual1;
};
class Prototype1{
//... some fields e.g. very similar to A1 A2 A3
};
class Prototype2{
//... some other field e.g. very similar to B1 B2 B3
Prototype1 prototype1;
};
问题
- (1)常见的是原型模式创建新的可维护性问题吗?
- (2)如果是,如何避免它?
- (3)如果没有,我在哪里错(尤其是编码的样式)?...或这种(重复代码)的趋势根本不是一个问题(即我只是恐慌。)?
我的可怜的解决方案
我认为将重复部分封装到名为Settings
的单个结构中可能是一个好主意。
class Settings{
bool isShootable;
float delayBetweenShoot;
float hp;
};
class Prototype{ //aka. "fake object"
public: Vec3 position;
Settings settings; //(#v.2)
};
class Actual{ //aka. "real object"
public: PhysicObject* rigidBody=nullptr;
Settings settings; //(#v.2)
};
但是,它可能会增加Prototype
和Actual
之间的不利凝聚力(即胶水或牢固的关系)。因此,它可能再次引起另一个新的可维护性问题。
您可以通过从原型中划分"实际'"来避免不必要的重复。例如:
struct Prototype {
bool isShootable = false;
float delayBetweenShoot = DEFAULT_DELAY;
float hp = DEFAULT_HP;
Vec3 position = STARTING_POSITION;
...
};
struct Actual : Prototype {
PhysicObject* rigidBody;
Actual() : Prototype(), rigidBody(new PhysicObject(position)) {}
}
int main() {
Actual actual;
// now you can access these methods
if (actual.isShootable) {
...
}
...
}
您的直觉是正确的,因为通过将"共同"字段分组在一起,您可以增加这些字段之间的耦合。从某种意义上说,耦合和代码重复之间存在权衡。由您确定最适合您申请的可接受折衷是什么。
可能使用不同类型(随后的双书保存)并不是对该设计模式的最佳解释。
有关避免双书保存并仍然具有基本想法的好处的方法,请参见下文 - 以预配合样本或模板对象,然后使用该实例来初始化许多其他实例。
class A {
int32_t id;
bool shootable;
bool moveable;
bool destructable;
public:
// A template instance specific constructor.
A(bool shoot, bool move, bool destruct)
: id(-1)
, shootable(shoot)
, moveable(move)
, destructable(destruct)
{
}
// One or more "real" instance constructors.
A(int32_t idval, const A& source)
: id(idval)
, shootable(source.shootable)
, moveable(source.moveable)
, destructable(source.destructable)
{
}
// ...
};
int main(int argc, const char *argv[])
{
A kind(true,false,true);
A instance0(1,kind);
A instance1(2,kind);
return 0;
}
作为上述想法的变体,您还可以存储对模板实例的引用,并且确实使用了两种类型。
class UnitType
{
int32_t hp;
bool ranged;
//...
};
class Unit
{
int32_t id;
const UnitType *type;
// more data
public:
Unit(int32_t idval, const UnitType* unitType)
: id(idval)
, type(unitType)
{
}
//...
};
当然,那么UnitType
实例不应按照实例进行写作。一次,还有例如currentHp
,您还有另一种复制形式可以处理。另外,您需要确保使用它的UnitType
模板实例超过每个Unit
实例的寿命。
- 在c代码之间共享数据的最佳方式
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 无法理解代码背后的逻辑,这是在两个给定数字之间生成素数的优化问题
- 两个代码段之间有什么区别?
- 当我使用按引用返回时,我不知道这些代码之间的区别
- 如何在括号与代码之间添加空格以进行C++?
- 为什么这个C++程序在代码::块和在线 IDE 之间返回不同的结果?
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- 在两个派生类之间执行专用代码
- 在Emscripten和Qt之间共享OpenGL代码
- 这两个代码之间的差异(为什么我的数组也有额外的空间,即使我限制了它)
- 无法将Android WebView渲染到C 和Java代码之间共享的外部纹理中
- 使用运行时参数与编译时参数在类之间共享代码
- 任何可以在单个 CPU 指令中在 0 和 1 之间翻转位/整数/布尔值的可能代码
- 为什么两个相同的代码给出不同的输出,而它们之间的唯一区别是不同的变量名称和写作样式
- 不理解连续数字之间的空格代码
- 这些代码之间的区别在哪里?输出不应该是一样的吗?
- Objective-C源代码和clang -rewrite-objc C++代码之间有什么关系?
- 框架代码和普通代码之间的区别
- 如何避免语法相同的常量和非常量函数之间代码重复,这些函数在语义上不相同