所以我正在努力改进现有的实施。我有许多多态类,它们都被组成一个更高级的容器类。我现在要处理的问题是,更高级别的容器类,很糟糕。它看起来像这样,我真的没有问题(因为容器中的多态类应该是公共的)。我真正的问题是构造函数......
/*
* class1 and class 2 derive from the same superclass
*/
class Container
{
public:
boost::shared_ptr<ComposedClass1> class1;
boost::shared_ptr<ComposedClass2> class2;
private:
...
}
/*
* Constructor - builds the objects that we need in this container.
*/
Container::Container(some params)
{
class1.reset(new ComposedClass1(...));
class2.reset(new ComposedClass2(...));
}
我真正需要的是使这个容器类更易于重用。通过对成员对象进行硬编码并实例化它们,它基本上不是并且只能使用一次。工厂是构建我需要的东西的一种方式(可能通过提供一个对象列表及其要创建的特定类型?)其他方法来解决这个问题?好像有人应该先解决它...谢谢!
答案 0 :(得分:3)
答案 1 :(得分:0)
如果在派生类中更改创建的类型,即使Container的后代使用class1和class2的不同后代,则使用工厂方法。
class1* Container::GetClass1; virtual;
{
return new ComposedClass1;
}
class1* SpecialContainer::GetClass1;
{
return new SpecialComposedClass1;
}
Container::Container(some params)
{
class1.reset(GetClass1);
class2.reset(GetClass2);
}
另一种方法是将Container的依赖关系与Container分离。 对于初学者,您可以将构造函数更改为依赖注入class1和class2。
Container::Container(aclass1, aclass2)
{
class1.reset(aclass1);
class2.reset(aclass2);
}
答案 2 :(得分:0)
你知道你可以只有第二个没有做到这一点的构造函数吗?
Container::Container(some params)
{
// any other initialization you need to do
}
然后,您可以随意设置class1和class2,因为它们是公开的。
当然他们不应该这样,但鉴于这个代码就是你可以做的。
据我所知,工厂模式不会那么有用。
答案 3 :(得分:0)
public class factory
{
public static Class1 Create()
{
return new Class1();
}
}
class Class1
{}
main()
{
Classs1 c=factory.Create();
}
答案 4 :(得分:0)
根据您的描述,我建议将一个抽象工厂传递给构造函数。
class ClassFactory {
public:
virtual ~ClassFactory
virtual Class1 * createClass1(...) = 0; // obviously these are real params not varargs
virtual Class2 * createClass2(...) = 0;
};
class DefaultClassFactory : public ClassFactory {
// ....
};
Container::Container(
some params,
boost::smart_ptr<ClassFactory> factory = boost::smart_ptr<ClassFactory>(new DefaultClassFactory))
{
class1.reset(factory->createClass1(...));
class2.reset(factory->createClass1(...));
}
这是一种没有框架的依赖注入形式。普通客户端可以像以前一样透明地使用DefaultClassFactory
。其他客户端(例如单元测试)可以注入自己的ClassFactory
实现。
根据您希望如何控制factory
参数的所有权,这可能是smart_ptr,scoped_ptr或引用。该引用可以使语法略微清晰。
Container::Container(
some params,
ClassFactory & factory = DefaultClassFactory())
{
class1.reset(factory.createClass1(...));
class2.reset(factory.createClass1(...));
}
void SomeClient()
{
Container c(some params, SpecialClassFactory());
// do special stuff
}
答案 5 :(得分:0)
一般来说,我同意汤姆斯评论:没有足够的信息。
根据您的澄清:
它只是许多“组件”的容器
如果组件列表不同,请在容器上提供Add / Enumerate / Remove方法。
如果应为容器的每个实例修复组件列表,请使用方法
提供构建器对象Builder.AddComponent
Builder.CreateContainer
第一个允许重用容器,但在我的经验中往往会变得更复杂。第二个通常需要一种交换/替换容器的方法,但最终更容易实现。
依赖注入库可以帮助您配置应用程序之外的实际类型(尽管我仍然需要了解为什么这是一个如此大的飞跃)。