Java 重构设计:抽象/接口/无?
首先,请查看我的UI,因为它将帮助您了解问题: 您将了解到,通过选择其中一个,您将得到一组具有相同目标但实施方式不同的类似操作(大多数情况下,Java 重构设计:抽象/接口/无?,java,optimization,interface,refactoring,abstract-class,Java,Optimization,Interface,Refactoring,Abstract Class,首先,请查看我的UI,因为它将帮助您了解问题: 您将了解到,通过选择其中一个,您将得到一组具有相同目标但实施方式不同的类似操作(大多数情况下,登录和注销)。这是一个Android项目(因此是用Java编写的) 这里的主要类是AuthUI。它设置所有的onClickEventListeners,以及单击按钮后要执行的操作。事实上,所有内容都包含在这个类中,但我的小指告诉我,重构代码可能是个好主意,这样我就不会在主类中看到GoogleSignIn和AcclimateSignIn的实际实现(与型号相
登录
和注销
)。这是一个Android
项目(因此是用Java
编写的)
这里的主要类是AuthUI
。它设置所有的onClickEventListeners
,以及单击按钮后要执行的操作。事实上,所有内容都包含在这个类中,但我的小指告诉我,重构代码可能是个好主意,这样我就不会在主类中看到GoogleSignIn
和AcclimateSignIn
的实际实现(与型号相比,它更能充当控制器
我一直在考虑将AcclimateAuth
和GoogleAuth
设置为与此AuthUI
类相同的Authentication
包中的独立类。但是,我想知道解决此问题的最佳方法是什么
我最初的想法是尝试在AuthUI
中将这两个新类声明为abstract
和extensions
,但后来我想起我只能扩展一个类。因此,第二步我选择了接口
方法,但决定在实际采取行动之前多想一想
我目前的想法是有一个名为Auth
的接口,它基本上会设置方法signIn
和signOut
,然后是两个新的类(AcclimateAuth
和GoogleAuth
)将实现该接口。AuthUI
将通过将它们作为private
属性访问这两个类
但是考虑到我只会有这两个新类的一个实例,也许我应该考虑他们的方法是“代码>静态< /代码>?还是这是一个糟糕的设计选择?
希望得到一些关于在这种情况下什么是好的重构技术的明确答案。我的想法
我建议使用接口模式
我为什么这么想
它不仅非常适合您的需求,还可以指定一个Auth接口,确保每个实现至少有一些默认方法(默认情况下可能是Signin和Signout方法)。除了有更多的实现之外,它还允许您做的另一件事是,您可以将依赖项注入到主控制器类构造函数中。这对可重用性非常有好处,因为如果我想有一个不同的实现,比如说使用其他服务登录,我可以扩展接口并创建我的类。如果不使用接口模式和控制器注入,我将不得不更改主控制器
类代码,并可能引入bug
如果您不想这样做:
不这样做的最佳情况是让控制器
类选择它在自己的带有枚举和switch语句的代码中使用的登录实现。例如,google按钮的按钮处理程序会将“登录”枚举设置为G或其他值,然后在“登录”枚举上有一个开关盒,该开关盒将查找G,然后运行google登录实现的代码。这可以作为一个过渡,但如果您有很多实现,它可能会变得混乱/不可读,而且它会引入O(n)时间复杂性,其中包含n个“实现”,因此n个切换情况,以确定您正在使用的实现。构造函数注入使O(1)成为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).
这甚至更好,因为您可以使用文本文件在运行时指定实现
关于静态方法的话题
如果您只有这些类的一个实例,并且不希望有多个对象四处浮动,那么请务必这样做。它将增加可读性,并允许您更直接地调用方法,而无需实例化对象。这主要取决于您是否真的需要多个实例。代码只是一个示例,可能包含语法错误等
我不推荐抽象类的原因。
当您有很多具体的子类/继承时,抽象类会更好。因为这里没有太多的继承,所以它更多的是容器关系,而不是继承关系。一个很好的类比可能是为动物园建模。如果你想对所有不同类型的动物建模,界面会更好。如果你想描述动物之间的关系,抽象类会更好。您的问题有不同类型的问题作为根本原因,而不是这两个或多个问题之间的关系。仅仅因为您有一个实例,并不意味着他们的方法应该是静态的。我推荐第二种方法。使用静态方法的缺点是什么?有趣的答案!请您澄清一下构造函数的注入
和依赖项的注入
是什么意思好吗?如果您的AuthUI
将SignInImpl
对象作为构造函数参数,就是一个例子。这里演示[链接]