【问题标题】:Best way to avoid duplicate code when using Fragments使用 Fragments 时避免重复代码的最佳方法
【发布时间】:2013-12-16 11:09:58
【问题描述】:

我在 Google Play 商店中准备并运行了一个应用程序,现在我正在实现片段。

所以,我已经有一个用一些方法扩展 B 的 A 类,现在我有 C 扩展 FragmentActivity 的类,所以现在我需要使用与 A 类中相同的方法,但由于我正在扩展 FragmentActivity,我无法使用B类的,所以这里有与A类相同的重复方法,但我需要重用这些方法。

下面这个例子显示了我的情况:

例如:

当前实施

class A extends B{

one();
two();

}

整合片段后,

例如:

class C extends FragmentActivity{

one();// same methods as in class A
two();// same methods as in class A

}

1) 在这种情况下重用这些方法的最佳方式是什么?如何实现?

2) 我的想法是创建一个类并将方法设为静态并在 A 和 C 类中重用方法,但是我的方法很好吗?我可以将方法设为静态吗?好办法?

3) 我想到的另一种方法“策略模式”。

Eg:
class A extends ApiClass {
   private ClassContainingDupMethod strategy;
}

class N extends AnotherApiClass {
   private ClassContainingDupMethod strategy;

   public methodCallingDupMethod(){
      strategy.dupMethod();
   }
}

class ClassContainingDupMethod{
   public dupMethod(){;}
}

“策略模式”。是一个好方法吗?因为我需要在两个类中创建公共类的对象。

对此的任何建议将不胜感激。

【问题讨论】:

  • 让您的问题更清楚,这将有助于我们更好地理解它。
  • @VipulPurohit 查看我的编辑
  • 您应该提供有关方法一和方法二的作用/目标的更多信息。可以将它们提取为服务方法并使其成为静态,或者在您想要使用这些方法的所有类中使用包含对类(已实现这些方法)的引用的“组合”。跨度>
  • @hovanessyan 在这里我的目标是尽可能避免重复方法,我不想使用静态方法,并且关于方法 one() 和 two() 方法它们具有相同的实现。
  • 建议:不要只从“最佳技术/编程方法”的角度来考虑解决方案——这可能并不重要。多想清楚、简单、易懂的解决方案。如果可能的话 - 进行模拟实现以展示不同的方法,并询问同事哪个对他来说更清楚。

标签: java android android-fragments


【解决方案1】:

它比你描述的更简单。您需要做的就是像这样创建 D:

public class D{
   one();
   two();
}

将 A 类改为 D 类。

   public Class A{
       public D dLogic;
   }

与 C 类相同。

public Class C extends FragmentActivity{
       public D dLogic;
   }

这是面向对象编程中非常基本的东西,它称为composition。

【讨论】:

    【解决方案2】:

    我怀疑你有一些实用方法,只需将它们放在类 Utils 中,将它们设为静态并从任何你想要的地方调用它们。我的应用程序中有很多实用程序类,例如WifiUtils、LogUtils、NumberUtils 等等。

    【讨论】:

      【解决方案3】:

      如果您想强制使用相同的 API,您可以尝试将接口添加到 A 和 C 类,同时将 A 的实例保留为 C 的字段。 C 将充当 A 的包装类。

      班级A:

      class A extends B implements CommonApi {
          public void one() {
              ...
          }
      
          public boolean two() {
              ...
          }
      }
      

      班级C:

      class C extends FragmentActivity implements CommonApi {
          private A a;
      
          public void one() {
              a.one();
          }
      
          public boolean two() {
              return a.two();
          }
      }
      

      【讨论】:

        【解决方案4】:

        尽可能地摆脱继承。你不需要它。类继承几乎总是一个坏主意,特别是如果您期望将来在实现中进行大量更改。唯一真正需要的是当一个设计不佳的框架需要您扩展一些基类时。

        在阅读 Gamma 等人的旧设计模式时,请记住,它们是为 C++ 和 Pascal 是主要 OO 语言的世界编写的。 Java 仍处于起步阶段,并引入了这些语言都没有的新颖性(接口)。所以,你应该在头脑中用工具替换很多扩展的使用,你最终会得到更好的代码。

        基本上,保持高一致性和低耦合是面向对象设计的一个好主意。类继承很容易导致高度耦合的类具有低一致性(一个类中有很多不相关的功能)。原因是基类最终具有并非所有子类都需要的功能,或者仅与某些子类相关的代码路径。此外,随着您的设计的发展,您最终会得到许多相互继承并且非常紧密耦合的类。我个人讨厌必须处理具有多级继承的代码。它很难阅读,继承的语义也使测试更加痛苦。除了接口,我从不使用扩展,自九十年代中期以来我一直在做 Java。

        @Babibu 建议使用组合和委托是一个更好的选择,因为这个原因。它会导致更连贯的类,而这些类的耦合度要低得多。更容易维护、更容易重构、更容易测试等。

        【讨论】:

          【解决方案5】:

          你应该从巴比布所说的开始——简单的作文。

          当你掌握了这个,还有其他的技术。例如,依赖注入看起来可以在这里使用。 简单的案例会是这样的。定义接口 B 而不是类 B。在 C 初始化期间将接口 B 作为参数传递,将其作为内部变量 b 并调用 b.one() 和 b.two()。 您必须创建一个在 C 范围之外实现 B 的对象 A,并在活动 C 初始化期间将其传入。 优点:C不需要知道如何创建A,以后可以改成AA或AAA,只要AA和AAA实现B就再也不会碰你的activity了。你不必重新测试C。

          【讨论】:

            【解决方案6】:

            如果您在两个片段中都有相同的方法,为什么不使用 BaseFragment 类(它又扩展了 FragmentActivity)并在其中包含所有常用方法。然后你可以在任何你想要的类中扩展这个 BaseFragment 类。 这样,您在 BaseFragment 中获得的任何方法都可以直接使用而无需重新定义。

            【讨论】:

              【解决方案7】:

              策略模式或“包装器”是最佳选择。而且我认为 Juan Sánchez 的解决方案比 Babibu 的解决方案更好。在 Babibu 的代码中,类 A 不应该依赖于 D。依赖于接口更好。 在您的代码中,如果 A 类包含 C 类不需要的某些属性或某些操作,您可以像下面这样重构您的代码。否则胡安的解决方案就足够了。 我已经为这种情况绘制了一个 UML 图像,但我没有足够的声誉来发布它:-( 代码是这样的:

              interface IAction
              {
                 public void actionA();
              }
              
              class A extends B implements IAction
              {
                 private IAction action;
                 public void actionA() {
                    action.actionA();
                 }
              }
              
              class C extends FragmentActivity implements IAction
              {
                 private IAction action;
                 public void actionA() {
                    action.actionA();
                 }
              }
              
              class D implements IAction
              {
                 public void actionA() {
                 // put implementation here
                 }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-09-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多