设计问题 generics/factory/abstract class
design issue generics/factory/abstract class
我是 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); //(**)
}
在 main 方法中我知道结果类型是什么。如果它是 BitmapType1,我必须应用 filterImageA。如果它是 BitmapType2,那么我必须使用 filterImageB。有通用的方法吗?我阅读了泛型,但不知道如何在这种特殊情况下使用它们。我希望这不会太混乱。也许整个方法都是废话。欢迎提出更好的建议!
创建两个不同的过滤器,而不是 filterImageA
和 filterImageB
:一个是 filterImage
做 filterImageA
做的事情,另一个是 filterImageB
.
然后在你的 main
中,你知道你想要 "A" 还是 "B",从工厂按名称获取正确的过滤器,并在其上调用 filterImage
。
我对这段代码有很多评论:
-
MyFactory
class 可以有像 add(String bitmapType, String filterType, ImageFilter filter)
这样的注册方法,这样可以保持动态。创建一个包含这两个值的 bean 作为 Map
的键(注意 equals()
和 hashCode()
来保存它们,你就完成了。实际上,你将有一个 ImageFilter
对于每个单个位图类型和过滤器处理。
- 这是个人选择,但我会把
ImageFilter
写成一个接口,如果需要的话 - 添加一个 AbstractImageFilter
使用模板方法来封装 pre/post 常见行为。
@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
反之亦然,您需要首先检查层次结构中最具体的 class:
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);
}
我是 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); //(**)
}
在 main 方法中我知道结果类型是什么。如果它是 BitmapType1,我必须应用 filterImageA。如果它是 BitmapType2,那么我必须使用 filterImageB。有通用的方法吗?我阅读了泛型,但不知道如何在这种特殊情况下使用它们。我希望这不会太混乱。也许整个方法都是废话。欢迎提出更好的建议!
创建两个不同的过滤器,而不是 filterImageA
和 filterImageB
:一个是 filterImage
做 filterImageA
做的事情,另一个是 filterImageB
.
然后在你的 main
中,你知道你想要 "A" 还是 "B",从工厂按名称获取正确的过滤器,并在其上调用 filterImage
。
我对这段代码有很多评论:
-
MyFactory
class 可以有像add(String bitmapType, String filterType, ImageFilter filter)
这样的注册方法,这样可以保持动态。创建一个包含这两个值的 bean 作为Map
的键(注意equals()
和hashCode()
来保存它们,你就完成了。实际上,你将有一个ImageFilter
对于每个单个位图类型和过滤器处理。 - 这是个人选择,但我会把
ImageFilter
写成一个接口,如果需要的话 - 添加一个AbstractImageFilter
使用模板方法来封装 pre/post 常见行为。
@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
反之亦然,您需要首先检查层次结构中最具体的 class:
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);
}