我正在研究设计专家,我有一种情况,我不确定什么是更好的做法:
我有一个类“类别”,它有几个字段:名称,2种网址,相关对象列表。有一个方法'toHtml()',它基本上从该类的实例生成一些HTML。
有4种不同类型的“类别”具有完全相同的字段,但“toHtml()”方法应为每种类型提供不同的结果。
我不确定是否应该传递一个参数“type”和一系列ifs / switch语句来生成不同的html,或者我应该创建一个Category类抽象并创建几个子类来覆盖toHtml()方法然后使用CategoryFactory类生成它们?在这两种情况下,我都需要传递'type'参数。
我试着考虑'关闭修改,打开扩展'OOP规则。但在这种情况下,如果我想添加'第五'类别类型,生成不同的html - 对于第一个解决方案,我只需要修改到HTML方法(如果添加一个),为第二个解决方案我需要创建额外的子类AND修改CategoryFactory类。
什么是更好的做法?当我遇到类似的困境时,我应该遵循哪些额外的规则吗?
答案 0 :(得分:0)
如果创建Category的子类并覆盖toHtml()方法,为什么需要具有工厂模式。如果使用引用调用它,则将调用运行时已解析类的toHtml()方法。这意味着如果你添加一个新的Category子类,那么你覆盖toHtml()方法,它应该工作正常。
答案 1 :(得分:0)
首先,我相信你指的是工厂方法,而不是抽象工厂模式。
主要区别在于,在前者中,您为单个产品定义了一个通用模板,而在后者中,您为一系列产品定义了一个模板。有关详细信息,请查看here。
在您的情况下,您希望为Category
定义模板。有了这个假设,这就是你的课程组的样子:
abstract class Category {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
abstract void toHtml();
}
class Category1 extends Category {
public override void toHtml() {
... // do something here
}
}
class Category2 extends Category {
public override void toHtml() {
... // do something else here
}
}
确实,这肯定是很多代码,并且很容易像这样表示:
class Category {
public void toHtml(Integer param) {
if(param == 1) { // do something for Category1
}
else { // do something for Category2
}
}
在一天结束时,这确实是一个设计决定。您可以考虑一些因素。这是一个不断变化的课程吗?这将被宣布为全球供客户使用吗?您希望客户如何使用它?
此时更容易的是采取阻力最小的路径。让一个类服务所有类别肯定会导致代码更少,而在Salesforce中,更少的代码总是更好的事情。但请考虑这一点:将您的功能提取到单独的类中可以实现更易维护的代码。您可能会发现编写一个类和if
语句墙更容易,但明天当您不在,并且那里出现严重故障时,有人必须查看您的代码才能确切地找出哪个if
引起了问题,他们会诅咒你。
请记住,继承是一种全有或全无的机制。如果您有一些常用功能,您可能会发现使用它特别有用,在这种情况下,您可以选择将其抽象到父类中,让您的孩子处理具体细节。