用于生成 PDF 的 class 层次结构设计
Design of a class hierarchy for generating a PDF
我基本上必须制作一个可以生成 PDF 的程序。 PDF 将有 3 种不同的页面类型:封面 sheet、一般 sheet 和封底 sheet。 header包含了相当多的信息,但是封面sheet的header和一般的sheet只有一项不同,然而,一项需要我将其他坐标向下移动。我附上一张图片来说明我的意思。
此外,classes 真正服务的唯一目的是保存值以表示矩形,这些矩形将用作在 pdf 中打印文本的目标。因此,除了构造函数之外,它们实际上不需要任何功能,只需初始化常量文件中的值。
我正在尝试使用 "good" 设计实践,但我不确定哪种方法更有效。似乎我无法使用共享公共元素的继承,因为我总是会在 classes 之一中得到我不需要的东西。我考虑过只使用组合并为 header 中的每个元素制作一个 class,这将解决问题,但我会有更多的 classes,这将是一个class 仅用于保存一个似乎效率不高的数据成员。
因此,对于如何使它成为一个更具凝聚力和更明智的设计的任何建议,我将不胜感激。
图片不是我目前拥有的,但它表示我需要的数据似乎耦合得很笨拙,或者我可能只是把它复杂化了。
正面 sheet、一般 sheet 和背面 sheet 的共同点是它们 是 sheet。因此,class 层次结构的一个很好的候选者是:
class sheet { .... };
class front_sheet : public sheet { ...};
class back_sheet : public sheet { ...};
class general_sheet : public sheet { ...};
在sheet
中,你应该把所有共同的元素,当然还有共同的行为(例如print()
、save()
、get_size()
、...) .
应该有一个成员函数来计算元素在页面中的位置。由于规则取决于页面的种类,它是sheet()
的虚函数,前后sheets可以覆盖默认函数。这种方法将帮助您轻松管理不同页面的不同布局。
class sheet {
public:
virtual void get_position (int item_no, int& x, int&y) { x=5; y=14*item_no; }
...
};
class back_sheet : public sheet {
public:
void get_position (int item_no, int& x, int&y) { x=5; y = (item==5 ? 14:0); }
...
};
由于继承确实对应于 "is-a" 关系,因此您将获得非常稳健的设计。
不过,您应该考虑 sheet 的内容。我在这里看到两个主要方向:
- 您可以管理容器中的项目(例如向量):在循环中组织输出比为每个项目复制粘贴类似代码行更容易
- 您应该问问自己这些项目是否可以有子项目(例如,一个区域可以包含多个子区域,例如带有一个框和框内框的打印布局)。在这种情况下,我建议使用 composite pattern
编辑; 在考虑了内容之后,可能值得再次回到 sheet 年代,并问问自己他们的行为到底有多少不同:
- 它们在整个生命周期中是否有不同的行为(为 PDF 生成获取数据或动态使用布局的不同方式?在这种情况下,class 层次结构是可以的。
- 或者,在采用了上面建议的动态结构之后,是否发现唯一的区别是您 create/construct 他们的方式?在这种情况下,值得考虑的是只保留一个 sheet class,但有三个结构 "engines",使用 prototype pattern or the builder pattern。然而,这将是您应用程序架构的重大转变。
我基本上必须制作一个可以生成 PDF 的程序。 PDF 将有 3 种不同的页面类型:封面 sheet、一般 sheet 和封底 sheet。 header包含了相当多的信息,但是封面sheet的header和一般的sheet只有一项不同,然而,一项需要我将其他坐标向下移动。我附上一张图片来说明我的意思。
此外,classes 真正服务的唯一目的是保存值以表示矩形,这些矩形将用作在 pdf 中打印文本的目标。因此,除了构造函数之外,它们实际上不需要任何功能,只需初始化常量文件中的值。
我正在尝试使用 "good" 设计实践,但我不确定哪种方法更有效。似乎我无法使用共享公共元素的继承,因为我总是会在 classes 之一中得到我不需要的东西。我考虑过只使用组合并为 header 中的每个元素制作一个 class,这将解决问题,但我会有更多的 classes,这将是一个class 仅用于保存一个似乎效率不高的数据成员。 因此,对于如何使它成为一个更具凝聚力和更明智的设计的任何建议,我将不胜感激。
图片不是我目前拥有的,但它表示我需要的数据似乎耦合得很笨拙,或者我可能只是把它复杂化了。
正面 sheet、一般 sheet 和背面 sheet 的共同点是它们 是 sheet。因此,class 层次结构的一个很好的候选者是:
class sheet { .... };
class front_sheet : public sheet { ...};
class back_sheet : public sheet { ...};
class general_sheet : public sheet { ...};
在sheet
中,你应该把所有共同的元素,当然还有共同的行为(例如print()
、save()
、get_size()
、...) .
应该有一个成员函数来计算元素在页面中的位置。由于规则取决于页面的种类,它是sheet()
的虚函数,前后sheets可以覆盖默认函数。这种方法将帮助您轻松管理不同页面的不同布局。
class sheet {
public:
virtual void get_position (int item_no, int& x, int&y) { x=5; y=14*item_no; }
...
};
class back_sheet : public sheet {
public:
void get_position (int item_no, int& x, int&y) { x=5; y = (item==5 ? 14:0); }
...
};
由于继承确实对应于 "is-a" 关系,因此您将获得非常稳健的设计。
不过,您应该考虑 sheet 的内容。我在这里看到两个主要方向:
- 您可以管理容器中的项目(例如向量):在循环中组织输出比为每个项目复制粘贴类似代码行更容易
- 您应该问问自己这些项目是否可以有子项目(例如,一个区域可以包含多个子区域,例如带有一个框和框内框的打印布局)。在这种情况下,我建议使用 composite pattern
编辑; 在考虑了内容之后,可能值得再次回到 sheet 年代,并问问自己他们的行为到底有多少不同:
- 它们在整个生命周期中是否有不同的行为(为 PDF 生成获取数据或动态使用布局的不同方式?在这种情况下,class 层次结构是可以的。
- 或者,在采用了上面建议的动态结构之后,是否发现唯一的区别是您 create/construct 他们的方式?在这种情况下,值得考虑的是只保留一个 sheet class,但有三个结构 "engines",使用 prototype pattern or the builder pattern。然而,这将是您应用程序架构的重大转变。