避免重复的代码块
Avoiding duplicate code blocks
我的代码中有这样的东西:
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;
}
如您所见,有两个相似的 switch case。
有什么方法可以将它们转换为使用 Java 7 的方法?
我尝试了一下,但 instanceof
很棘手。
None 我的尝试值得在这里发布。
注意:Fragment
和 DownloadFragment
扩展 Fragment
。
They both extend Fragment
好吧,那么除了创建实例之外,您确实需要使用特定的子类。只需将当前 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;
As you can see there are two similar switch cases. Any way I could
convert them to a method using Java 7? I tried a bit but the
instanceof is tricky.
为了避免 switch case 并用直接方法调用替换它们,您可以使用 object 和多态性。
在您的情况下,您可以引入一个带有方法的接口:
public interface Processing{
Fragment doProcess();
}
您可以有两种实现方式(根据代码中的项目 ID):
DownloadManagerProcessing
ReadProcessing
然后,您可以使用工厂 returns 方便的 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 那样从没有强重复的代码开始,您可以再次使用方法来避免 switch case。
在此版本中,您可以使用工厂来检索 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 中有一个 public 方法 getType()
其中 returns 一个 String 或一个 Enum 并且将由每个 children class.
但在某种程度上,它有点像 instanceof
。
在您的客户端代码中,您可以这样做:
currentFragment = FragmentFactory.createInstanceIfNeeded(item.getItemId());
if (currentFragment==null){
return false;
}
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
currentDrawerItem = item.getItemId();
return true;
就我个人而言,我不喜欢使用 switch case。我找到了 error-prone.
我的代码中有这样的东西:
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;
}
如您所见,有两个相似的 switch case。
有什么方法可以将它们转换为使用 Java 7 的方法?
我尝试了一下,但 instanceof
很棘手。
None 我的尝试值得在这里发布。
注意:Fragment
和 DownloadFragment
扩展 Fragment
。
They both extend Fragment
好吧,那么除了创建实例之外,您确实需要使用特定的子类。只需将当前 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;
As you can see there are two similar switch cases. Any way I could convert them to a method using Java 7? I tried a bit but the instanceof is tricky.
为了避免 switch case 并用直接方法调用替换它们,您可以使用 object 和多态性。 在您的情况下,您可以引入一个带有方法的接口:
public interface Processing{
Fragment doProcess();
}
您可以有两种实现方式(根据代码中的项目 ID):
DownloadManagerProcessing
ReadProcessing
然后,您可以使用工厂 returns 方便的 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 那样从没有强重复的代码开始,您可以再次使用方法来避免 switch case。 在此版本中,您可以使用工厂来检索 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 中有一个 public 方法 getType()
其中 returns 一个 String 或一个 Enum 并且将由每个 children class.
但在某种程度上,它有点像 instanceof
。
在您的客户端代码中,您可以这样做:
currentFragment = FragmentFactory.createInstanceIfNeeded(item.getItemId());
if (currentFragment==null){
return false;
}
fragmentTransaction.replace(R.id.container,
currentFragment).commit();
currentDrawerItem = item.getItemId();
return true;
就我个人而言,我不喜欢使用 switch case。我找到了 error-prone.