【问题标题】:Refactoring design: abstract/interface/none?重构设计:抽象/接口/无?
【发布时间】:2018-07-25 19:53:43
【问题描述】:

首先,看看我的 UI,因为它可以帮助你理解问题:

您会明白,通过选择另一个,您最终会得到一组具有相同目标但实现不同的类似操作(大部分情况下是Sign inSign out)。这是一个Android 项目(因此写在Java)。

这里的主要类是AuthUI。它设置所有onClickEventListeners 以及单击按钮后要执行的操作。事实上,所有内容都包含在这个类中,但我的小指告诉我,重构代码可能是个好主意,这样我就看不到 GoogleSignInAcclimateSignIn 的实际实现在那个 main类(应该比 Model 更多地充当 Controler)。

我一直在考虑将AcclimateAuthGoogleAuth 设置为与此AuthUI 类相同的Authentication 包中的单独类。但是,我想知道解决这个问题的最佳方法是什么

我最初的想法是尝试在AuthUI 中将这两个新类声明为abstractextends,但后来我记得我只能扩展一个类。所以其次我选择了Interface 方法,但决定在实际采取行动之前多考虑一下。

我的当前想法是有一个名为Auth 的接口,它基本上会设置方法signInsignOut,然后是两个新的classesAcclimateAuth 和@987654344 @) 将 implement 那个接口。 AuthUI 可以通过将它们作为private 属性访问这两个类。

但考虑到我只会拥有这两个新类的一个实例,也许我应该考虑将它们的方法设为static?或者这是一个糟糕的设计选择?

希望就在这种情况下什么是好的重构技术得到一些明确的答案。 :)

【问题讨论】:

  • 仅仅因为你有一个实例并不意味着它们的方法应该是静态的。我会推荐第二个选项。
  • 使用static 方法有什么缺点?

标签: java optimization interface refactoring abstract-class


【解决方案1】:

我的想法

我会推荐接口模式。

我为什么这么认为

它不仅非常适合您的要求,您还可以指定一个身份验证接口,以确保每个实现至少有一些默认方法(例如,默认情况下可能是登录和注销方法)。除了拥有更多实现之外,它还可以让您做的另一件事是您可以将依赖项注入到您的主 Controller 类构造函数中。这对可重用性非常有用,因为如果我想要一个不同的实现来使用其他服务登录,我可以扩展接口并创建我的类。如果不使用接口模式和委托人注入,我将不得不更改主要的 Controller 类代码并可能引入错误。

如果你不想那样做:

不这样做的最佳情况是让Controller 类通过 ENUMS 和 switch 语句选择它在自己的代码中使用的登录实现。例如,您的 google 按钮的按钮处理程序会将“登录”ENUM 设置为 G 或其他内容,然后您将在“登录”ENUM 上设置一个开关盒,用于查找 G,然后运行 ​​Google 登录的代码执行。这作为一个过渡很好,但如果你有很多实现,它可能会变得混乱/不可读,而且它会引入一个 O(n) 时间复杂度和 n 个“实现”,因此 n 个切换案例只是为了找到你正在使用的实现。构造函数注入使 O(1) 成为可能,因为您可以立即获得所需的实现。您还可以使用简单的属性文件设置配置。类似于:“SignInImpl=Google”作为名为“properties.config”的文本文件中的一行。 然后你可以用类似的东西加载这个属性文件

Properties prop = new Properties();
    try {
        prop.load(YOURCLASSNAMEHERE.class.getResourceAsStream("config.properties"));

然后您的 SingInImpl 对象可以使用反射制作成您需要的任何东西。

SignInImpl ImplYouWant = Class.forname(//put the property value here to find your class implementation). 

这更好,因为您可以在运行时使用文本文件指定实现。

关于静态方法的话题

如果您只有这些类的一个实例,并且您不想让多个对象四处浮动,那么无论如何。它将增加可读性并允许您更直接地调用方法,而无需实例化对象。这主要取决于您是否真的需要多个实例。代码只是一个示例,可能包含语法错误等。

我不推荐抽象类的原因。

当你有很多具体的子类/继承时,抽象类会更好。由于这里没有太多继承,它更多的是容器关系而不是继承关系。一个很好的类比可能是为动物园建模。如果您想对您拥有的所有不同类型的动物进行建模,界面会更好。如果你想描述动物之间的关系,抽象类会更好。您的问题的根本原因是不同类型的事物,而不是这两个或更多事物之间的关系。

【讨论】:

  • 有趣的答案!您介意澄清injection of constructorsinjection of dependencies 的意思吗?
  • 如果您的 AuthUISignInImpl 对象作为构造函数参数,这就是一个例子。这里演示了[link]en.wikipedia.org/wiki/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 2011-05-22
  • 2011-07-12
  • 1970-01-01
相关资源
最近更新 更多