设计问题泛型/工厂/抽象类



我是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);
        }

而不是 filterImageAfilterImageB ,创建两个不同的过滤器:一个让它filterImagefilterImageA做的事情,另一个用于filterImageB。然后在您的main中,您知道是要"A"还是"B",请按名称从工厂获取正确的过滤器,并在其上调用filterImage

我对这段代码有很多评论:

  • MyFactory类可以具有类似于add(String bitmapType, String filterType, ImageFilter filter)的注册方法,以便可以保持动态。创建一个 bean,将这两个值作为Map的键(注意equals()hashCode()保存它们,你就完成了。实际上,您将对每个位图类型和筛选器处理进行ImageFilter
  • 这是个人选择,但我会ImageFilter编写为接口,并在需要时使用模板方法添加AbstractImageFilter来封装前/后常见行为。

最新更新