避免重复的代码块

时间:2016-08-20 16:45:34

标签: java android fragmentmanager

我的代码中有这样的内容:

        switch (item.getItemId()) {
            case R.id.search:
                if (currentFragment == null || !(currentFragment instanceof ClipsFragment)) {
                    ClipsFragment clipsFragment = new ClipsFragment();
                    fragmentTransaction.replace(R.id.container,
                            clipsFragment).commit();
                    currentFragment = clipsFragment;
                } else {
                    fragmentTransaction.replace(R.id.container,
                            currentFragment).commit();
                }
                currentDrawerItem = R.id.search;
                return true;
            case R.id.download_managers:
                if (currentFragment == null || !(currentFragment instanceof DownloadFragment)) {
                    DownloadFragment downloadFragment = new DownloadFragment();
                    fragmentTransaction.replace(R.id.container,
                            downloadFragment).commit();
                    currentFragment = downloadFragment;
                } else {
                    fragmentTransaction.replace(R.id.container,
                            currentFragment).commit();
                }
                currentDrawerItem = R.id.search;
                return true;

            default:
                return false;
        }

正如您所看到的,有两种类似的开关情况 有没有办法将它们转换为使用Java 7的方法?
我尝试了一下,但instanceof很棘手 我的所有尝试都不值得在这里发布。

注意:FragmentDownloadFragment延长Fragment

2 个答案:

答案 0 :(得分:1)

  

他们都扩展了片段

好的,那么除了创建实例之外,您还需要使用特定的子类。只需将当前的Fragment声明为那些新实例。

这对你来说更干净吗?

boolean handled = true;
switch (item.getItemId()) {
    case R.id.search:
        if (currentFragment == null || !(currentFragment instanceof ClipsFragment)) {
            currentFragment = new ClipsFragment();
        }
        break;
    case R.id.download_managers:
        if (currentFragment == null || !(currentFragment instanceof DownloadFragment)) {
            currentFragment = new DownloadFragment();
        }
        break;
    default:
        handled = false;
}

if (currentFragment != null) {
    fragmentTransaction.replace(R.id.container,
            currentFragment).commit();
}
if (handled) {
    currentDrawerItem = item.getItemId();
}

return handled;

答案 1 :(得分:0)

  

正如您所看到的,有两种类似的开关案例。我能以任何方式   将它们转换为使用Java 7的方法?我尝试了一下但是   instanceof很棘手。

为了避免切换案例并通过直接方法调用替换它们,您可以使用对象和多态。 在您的情况下,您可以使用方法引入接口:

public interface  Processing{
    Fragment doProcess();
}

你可以有两个这样的实现(根据代码中的项目ID):

  • DownloadManagerProcessing
  • ReadProcessing

然后,您可以使用返回方便Processing实例的工厂:

public ProcessingFactory{
  ..
  Map<Integer, Processing> processingByItemId;
  ..
  public Processing getProcessing(int itemId){
     return processingByItemId.get(itemId);
   }
..
}

你切换案例:

 switch (item.getItemId()) {
            case R.id.search:
             ... 
            case R.id.download_managers:
            ...
            default:
            return false;
  }

将替换为:

Processing processing = ProcessingFactory.getProcessing(itemId);
if (processing==null){
   return false;
}
Fragment fragment = processing.doProcess();
return true;

在这个解决方案中,我们总是依赖于itemId,但是将它们与处理相关联的工作是孤立的 因此,如果需要,您可以依赖itemId在工厂中添加其他类型的处理,而无需担心其映射。

编辑(从清洁代码开始实施)

从cricket_007没有强重复的代码开始,你可以再次使用方法来避免切换案例。 在此版本中,您可以使用工厂检索ItemId的匹配实例:

public FragmentFactory{
  ..

  ..
  public Fragment createInstanceIfNeeded(Fragment currentFragment, int itemId){


     if(itemId ==...){
        if (!(currentFragment instanceof ClipsFragment)) {
          return new ClipsFragment();
       }
     }
     else if(itemId == ..){
         if (!(currentFragment instanceof DownloadFragment)) {
          return new DownloadFragment();
       }
     }
     return currentFragment;
   }
..
}

在您的情况下需要instanceof,因为如果不符合您的预期,您希望更改实施。如果你想避免它,你应该在Fragment中有一个公共方法getType(),它返回一个String或一个Enum,它将由每个子类实现。 但在某种程度上它是instanceof之类的。

并在您的客户端代码中执行:

currentFragment = FragmentFactory.createInstanceIfNeeded(item.getItemId());

if (currentFragment==null){
   return false;
}

fragmentTransaction.replace(R.id.container,
            currentFragment).commit();
currentDrawerItem = item.getItemId();

return true;

就个人而言,我不喜欢使用开关盒。我发现它容易出错。