理论:
模板方法模式允许您在超类的方法中定义算法的骨架,即所谓的模板方法.
在此模板方法中,调用一个或多个抽象方法来完成算法的某些步骤.这种抽象方法有时被称为占位符方法.
由于它们是抽象的,因此这些步骤在超类中没有实现.相反,它们以不同的方式由子类实现,因此在特定的子类实例上调用继承的模板方法将使用它提供的占位符运行算法.
执行:
考虑使用泛型来实现更强大的模板模式,以及将占位符方法定义为受保护的,因为它们只能在模板方法中调用.
如果您不想让子类覆盖模板方法,请在抽象超类中将其声明为final.
我假设您的示例中的BufferedImage和ImageIcon都是Image的子类,并且模板方法(算法)必须显示带有其标题的图像:
// Class that defines the template method
// Generic parameter allows to define the specific type of image
// that will be handled by this image renderer
public abstract class ImageRenderer {
// This is the template method
// It's final to avoid that subclasses override it
public final void display(String title, T image) {
// Display title
this.displayTitle(title);
// Let subclasses display specific type of image
this.displayImage(image);
}
// Display title for every image type
// This method is private since it's only called
// from within the template method
// (make it protected if you want to let subclasses
// override it, i.e. for custom title displaying)
private void displayTitle(String title) {
// Display title, no matter the image type
}
// Placeholder method, no implementation
// Actual implementation is delegated to subclasses
protected abstract void displayImage(T image);
}
BufferedImageRenderer类需要通过覆盖它来为displayImage()方法提供实现.这里是泛型有很大帮助的地方,因为displayImage()方法参数不需要下载:
public class BufferedImageRenderer
extends ImageRenderer {
@Override
protected void displayImage(BufferedImage image) {
// Display specific buffered image
}
}
相同的注意事项适用于ImageIconRenderer类:
public class ImageIconRenderer
extends ImageRenderer {
@Override
protected void displayImage(ImageIcon image) {
// Display specific image icon
}
}
然后,只要您需要显示特定图像及其标题,只需创建适当的渲染器并调用模板方法,即对于ImageIcon:
ImageIcon icon = getImageIconFromSomePlace();
String iconTitle = "My pretty icon";
ImageIconRenderer renderer = new ImageIconRenderer();
renderer.displayImage(iconTitle, icon);
感谢泛型,如果您尝试使用渲染器无法处理的图像调用displayImage(),您将收到一个comnpilation错误:
BufferedImage bufferedImage = getBufferedImageFromSomePlace();
String bufferedImageTitle = "My amazing buffered image";
ImageIconRenderer renderer = new ImageIconRenderer();
renderer.displayImage(bufferedImageTitle, bufferedImage); // compilation error