我是Java编程新手,我有一个设计问题。目前我得到的是以下内容:
public class MyFactory {
private MyFactory(){
//hidden constructor
}
public static ImageFilter getInstance(String filterType){
if(filterType == “foo“){
return new FooFilter();
}
return null;
}
}
public abstract class ImageFilter {
public abstract Bitmap filterImage(byte[] data);
//some other stuff
}
public class FooFilter extends ImageFilter {
public C filterImage(byte[] data){
//want to apply filterImageA or filterImageB depending what I put in
//at (*) and (**)
}
private A filterImageA(byte[] data){
//
}
private B filterImageB(byte[] data){
//
}
}
void main(byte[] data) {
ImageFilter bar = MyFactory.getInstance(“foo“);
BitmapType1 myBitmap = bar.filterImage(byte[] data); //(*)
BitmapType2 myBitmap2 = bar.filterImage(byte[] data); //(**)
}
在主要方法中,我知道结果类型是什么。如果是BitmapType1,我必须应用filterImageA。如果是BitmapType2,那么我必须使用filterImageB。有没有通用的方法可以做到这一点?我读过泛型,但不知道如何在这种特殊情况下使用它们。我希望这不会太令人困惑。也许整个方法都是废话。随时建议一个更好的!
@Dima的回答是正确的。但您也可以使ImageFilter
更通用
public class MyFactory {
private MyFactory(){
//hidden constructor
}
public static ImageFilter getInstance(String filterType){
if(filterType == “foo“){
return new FooFilter();
}
return null;
}
}
public abstract class ImageFilter {
public abstract <T extends Bitmap> T filterImage(byte[] data, Class<T> clazz);
//some other stuff
}
public class FooFilter extends ImageFilter {
public <T extends Bitmap> T filterImage(byte[] data, Class<T> clazz){
if (BitmapType1.class.isAssignableFrom(clazz)) {
return this.filterImageA(data);
} else if (BitmapType2.class.isAssignableFrom(clazz)) {
return this.filterImageB(data);
}
return null; // or better throw runtime exception
}
private BitmapType1 filterImageA(byte[] data){
//
}
private BitmapType2 filterImageB(byte[] data){
//
}
}
void main(byte[] data) {
ImageFilter bar = MyFactory.getInstance(“foo“);
BitmapType1 myBitmap = bar.filterImage(byte[] data, BitmapType1.class);
BitmapType2 myBitmap2 = bar.filterImage(byte[] data, BitmapType2.class);
}
注意:如果BitmapType1
继承(直接或间接)自BitmapType2
,反之亦然,则需要首先检查层次结构中最具体的类:
if (BitmapType1.class.isAssignableFrom(clazz)) { // BitmapType1 type more concrete
return this.filterImageA(data);
} else if (BitmapType2.class.isAssignableFrom(clazz)) { // BitmapType2 type more general
return this.filterImageB(data);
}
而不是 filterImageA
和 filterImageB
,创建两个不同的过滤器:一个让它filterImage
做filterImageA
做的事情,另一个用于filterImageB
。然后在您的main
中,您知道是要"A"还是"B",请按名称从工厂获取正确的过滤器,并在其上调用filterImage
。
我对这段代码有很多评论:
MyFactory
类可以具有类似于add(String bitmapType, String filterType, ImageFilter filter)
的注册方法,以便可以保持动态。创建一个 bean,将这两个值作为Map
的键(注意equals()
并hashCode()
保存它们,你就完成了。实际上,您将对每个位图类型和筛选器处理进行ImageFilter
。- 这是个人选择,但我会
ImageFilter
编写为接口,并在需要时使用模板方法添加AbstractImageFilter
来封装前/后常见行为。