问题描述
我已经制作了这四个类,我想知道我是否正确使用了模板方法设计模式,因为我真的在这个主题上苦苦挣扎。
我使用了 getPrijsBehandeling() 和 getBeschrijvingBehandeling() 方法作为我的抽象类。
我还想知道我是应该在 UML 中使用抽象方法还是只在代码中使用。
由于这是我第一次使用设计模式,我想知道我是否在正确的轨道上。
public abstract class Behandeling {
private String beschrijving;
private double prijs;
private int behandelingsNummer;
private Wassen wassen;
public Behandeling(int behandelingsNummber,int keuze) {
this.behandelingsNummer = behandelingsNummber;
if(keuze == 3 || keuze == 4) {
wassen = new Wassen();
}
}
public abstract double getPrijsBehandeling();
public abstract String getBeschrijvingBehandeling();
public double getPrijs() {
prijs = getPrijsBehandeling();
if(wassen != null) {
prijs += wassen.getPrijsBehandeling();
}
return prijs;
}
public String getBeschrijving() {
beschrijving = getBeschrijvingBehandeling();
if(wassen != null) {
beschrijving += wassen.getBeschrijvingBehandeling();
}
return beschrijving;
}
public int getBehandelingsNummer() {
return behandelingsNummer;
}
}
------------------------------------------
public class Verven extends Behandeling {
public Verven(int behandelingsNummer,int keuze) {
super(behandelingsNummer,keuze);
}
@Override
public double getPrijsBehandeling() {
return 20;
}
@Override
public String getBeschrijvingBehandeling() {
return "Haren worden geverfd";
}
}
---------------------------------------------
public class Knippen extends Behandeling{
public Knippen(int behandelingsNummer,keuze);
}
@Override
public double getPrijsBehandeling() {
return 15;
}
@Override
public String getBeschrijvingBehandeling() {
return "Haren worden geknipt";
}
}
-----------------------------------------------------
public class Wassen {
private double prijs;
private String beschrijving;
public Wassen() {
this.prijs = 7.50;
this.beschrijving = " en haren worden gewassen";
}
public double getPrijsBehandeling() {
return prijs;
}
public String getBeschrijvingBehandeling() {
return beschrijving;
}
}
解决方法
方法(也就是“操作”,在 UML 中)geefPrijs()
和 geefBeschrijving()
确实是根据模板方法模式设计的:基类实现了通用算法,封装了“原始”部分可能需要专门化为可以被类扩展覆盖(即“专门化”,在 UML 中)的单独方法。
如果基类不能提供它自己的“部分”方法的实现,你可以把它抽象化。但是,尽管这是模式通常的描述方式,但实际上这不是义务:基类提供不总是被覆盖的默认行为是完全有效的。如果有抽象元素,UML 图应该反映您在这方面的设计。
一些额外的提示
在您的设计中,getPrijs()
(模板方法)和 getPrijsBehandeling()
(模板方法中使用的原语)都是公共的,并且名称可能会造成混淆:
- 如果原语不打算用于其他目的,那么将其设为
protected
可能是一个好主意,这是一种罕见的情况。 - 如果您不想使用
protected
,可以使用命名约定。 GoF 建议使用“do”前缀,其灵感来自于一个没有生存的框架。我更喜欢像preparePrijsBehandeling()
和prepareBeschrijvingBheandeling()
这样的“准备”,因为它会立即提出“准备什么?”的问题。防止不当使用。 - 这里不是这种情况,但当然,如果原语是在模板方法之外有意义的原语操作,那么就没有问题(例如:
surface()
或perimeter()
或 { {1}} 是形状的几何特征,可能与某些模板方法相关,但本身就有意义)。