针对此重构问题的不同方法 - Java Switch Case Alternative?

时间:2015-07-04 08:57:29

标签: java android

所以我有这个代码在现场摄像机预览中应用了许多过滤器。 框架在onSurfaceTextureUpdated上的纹理视图上绘制。

我有一个用户点击某个项目的listView。该项目取决于它的位置,如果它是3,例如它将调用过滤器3。

现在的问题是我的onSurfaceTextureUpdated你可以想象我有一个很大的转换声明。我想知道我是否可以将它重构为更好的结构。我可以使用EventListener或其他任何东西吗?

这是我的代码的一部分(想象一下案例中的一些随机代码)

public void onSurfaceTextureUpdated(SurfaceTexture surface) {

bmp = mTextureView.getBitmap();
bmpCopy = bmp.copy(bmp.getConfig(),true);

switch(processingFunction){
    case 0: 

        break;
    case 1: 

        break;
    case 2: 

        break;
    case 3: 

        break;
    case 4: 

        break;
    case 5: 

        break;
    case 6:

        break;
    case 7: 

        break;
    }
}

现在在每种情况下都有一些我懒得包含的代码。 这会增长。成像具有30多种功能。我不想以一个巨大的文件结束。那么替代方案是什么?

3 个答案:

答案 0 :(得分:3)

如果我理解您的问题,您需要查看Factory Pattern

您可能必须创建30多个类(取决于您的案例数),但这是一种干净的方法,易于维护并生成可读代码。添加或删除过滤器也很简单,只需删除该类并将其从FilterFactory hashmap中删除。

创建界面:过滤器

 public interface Filter {
    void Filter();
 }

创建一个工厂,根据您的processingFunction返回正确的过滤器。现在您可以使用以下内容代替您的开关案例:

  Filter filter = FilterFactory.getFilter(processingFunction);
  filter.filter();

编写FilterFactory的一种常用方法是在其中使用HashMap

public class FilterFactory{
   static{
     HashMap<Integer, Filter> filterMap = new HashMap<>();
     filterMap.put(0,new Filter0());
     ...
   }
   // this function will change depending on your needs
   public Filter getFilter(int processingFunction){
       return filterMap.get(processingFunction);
   }

}

像这样创建过滤器:(虽然名字有意义)

public class Filter0 implements Filter {

    public void filter(){
      //do something
    }
}

答案 1 :(得分:2)

我真的不明白为什么人们在谈论使用Reflection来简化代码?

您的问题是应用策略设计模式的典型案例: https://en.m.wikipedia.org/wiki/Strategy_pattern

维基百科的文章将比我更好地解释它。在您的情况下,您想要创建一个Filter接口,其中一个抽象方法是处理函数。另一个可以返回过滤器名称和描述。

您的应用程序模型中可能已经有Filter对象,以便能够向用户显示它们,以便他可以选择它们。确保你让它们都实现了相同的接口,这样你的代码就可以通用的方式处理它们。

答案 2 :(得分:1)

我假设你想要类似方法的东西。有两种方法可以实现这一目标。第一种方法是使用反射。它需要较少的编码,但会降低性能,因为java中的反射是性能贪婪的。第二种方式(更可取的是)命令模式。我遇到了像你这样的情况,并测试了反射与命令模式的性能。命令模式每1000次调用大约快30到50ms。这看起来似乎没什么大不同,但如果您的程序经常调用这些方法(图形更新,模块交互等等),您可以注意到它。

命令模式

<强>处理器

interface ProcessorMethod{
  public void invoke();
}

<强> ProcessorsFactory

class ProcessorsFactory{

  private Processor processor;      
  private HashMap<Integer, ProcessorMethod> processors;

  public ProcessorsFactory(Processor p){
    processor = p;
    processors = new HashMap<>();

    processors.put(new Integer(0), new ProcessorMethod(){
                                        @Override
                                        public void invoke(){
                                         processor.processFunction_0();}
    });


    processors.put(new Integer(1), new ProcessorMethod(){
                                        @Override
                                        public void invoke(){
                                         processor.processFunction_1();}
    });
                                   .
                                   .
                                   .
  }    


 public ProcessorMethod getProcessor(int processorIndex){
   return processors.get(new Integer(processorIndex));
}

<强>处理器

class Processor{

  public void processFunction_1() {.......}

  public void processFunction_2() {.......}
     .
     .
     .
}

某些课程

 Class SomeClass{

  ProcessorsFactory factory;
  Processor processor;

  public SomeClass(){
    processor = new Processor();
    factory = new ProcessorsFactory(processor);
  }

  public void doSomething(int processingFunction){
    factory.getProcessor(processingFunction).invoke();
  }

}

反射

<强> ProcessorsFactory

    class ProcessorsFactory{
       private HashMap<Integer, Method> processingFunctions = new HashMap<>();

      public ProcessorsFactory(Processor processors){
          Class processorsClass = processors.getClass();
          int count = 0;
          for(Method m : processorsClass.getDeclaredMethods())
            if(m.getName().startsWith("processFunction")
                processingFunctions.put(new Integer(count++), m)
          }               
      }

      public Method getProcessor(int processorIndex){
          return processingFunctions.get(new Integer(processorIndex))};

    }

<强>处理器

class Processor{

  public void processFunction_1() {.......}

  public void processFunction_2() {.......}
         .
         .
         .
}

<强> SomeClass的

Class SomeClass{

ProcessorsFactory factory;
Processor processor;

  public SomeClass(){
    processor = new Processor();
    factory = new ProcessorsFactory(processor);
  }

    public void doSomething(int processingFunction){
      factory.getProcessor(processingFunction).invoke(processor, arg1,   arg2. . .)
    }

}

如果你不经常使用这些方法,可以随意使用Reflections。如果您想获得更好的性能,请选择命令模式。

<强> P.S 这不是复制粘贴的代码片段,而是我所知道并使用过的原则。你应该根据你的需要进行重构。我建议你学习 设计模式。 Derek Banas youtube chanell是一个很好的起点。他知道如何解释这些事情。干杯:)