Refactoring design: abstract/interface/none?

Multi tool use


Refactoring design: abstract/interface/none?
First, have a look at my UI since it'll help you understand the problem:
You'll understand that by selection one of the other, you end up with a set of similar actions with the same goal, but different implementations (Sign in
and Sign out
, for the most part). It is an Android
project (thus written in Java
).
Sign in
Sign out
Android
Java
The main class here is AuthUI
. It sets up all the onClickEventListeners
and the actions to be taken once the buttons are clicked. As it is, everything is contained within this single class, but my little pinky tells me that it might be a good idea to refactor the code so that I don't see the actual implementations of GoogleSignIn
and AcclimateSignIn
within that main class (which should act as a Controler more than the Model).
AuthUI
onClickEventListeners
GoogleSignIn
AcclimateSignIn
I've been thinking about setting up AcclimateAuth
and GoogleAuth
as separate classes within the same Authentication
package as this AuthUI
class. However, I'm wondering what would be the best way to approach this problem.
AcclimateAuth
GoogleAuth
Authentication
AuthUI
My initial thought was to try to declare both those 2 new classes as abstract
and extends
them in AuthUI
, but then I remembered I could only extend one class. So secondly I went for the Interface
approach, but decided to think a bit more before actually making a move.
abstract
extends
AuthUI
Interface
My current thought is to have an Interface called Auth
which would basically setup the methods signIn
and signOut
, and then two new classes
(AcclimateAuth
and GoogleAuth
) would implement
that Interface. The AuthUI
would have access to both of those classes through having them as private
attributes.
Auth
signIn
signOut
classes
AcclimateAuth
GoogleAuth
implement
AuthUI
private
But considering I'll only ever have a single instance of those two new classes, maybe I should consider having their methods as static
? Or would that be a poor design choice?
static
Hoping to get some clear answers on what would be a good refactoring technique in this situation. :)
1 Answer
1
What I think
I would recommend The Interface Pattern.
Why I think it
Not only does it fit your requirement pretty perfectly, You can specify an Auth Interface that makes sure each Implementation has at least some default methods (Example might be a Signin and Signout method by default). The other thing it lets you do besides have more implementations is you can inject the dependencies into your main Controller
class contructor. This is really good for reusability since if I want to have a different implementation to say sign in with some other service, I can extend the interface and create my class. Without using interface pattern and contrustor injection I would have to change the main Controller
class code and potentially introduce bugs.
Controller
Controller
If you don't want to do it that way:
Best Case scenario for not doing it that way would be to have the Controller
class select which sign in implementation it uses in its own code with ENUMS and a switch statement. For example, the button handler for your google button would set a "Sign in" ENUM to G or something and then youd have a switch case on the "Sign In" ENUM that would look for G and then run the code for Google's sign in implementation. This is fine as an interim but If you have alot of implementations it can get messy/unreadable plus it would introduce an O(n) time complexity with n "implemenations" and hence n switch cases just to find which implementation you were using. Constructor injection makes that O(1) because you immediately get the implementation you want. You could also set a configuration using a simple properties file. Something like: "SignInImpl=Google" as a line in a text file named "properties.config".
Then you can load this properties file with something like
Controller
Properties prop = new Properties();
try {
prop.load(YOURCLASSNAMEHERE.class.getResourceAsStream("config.properties"));
and then your SingInImpl Object can be made into whatever you need using reflection.
SignInImpl ImplYouWant = Class.forname(//put the property value here to find your class implementation).
Thats even better since you can specify implementation at runtime with a text file.
On the Topic of static methods
If you only have one instance of these Classes and you don't want to have multiple objects floating around then by all means. It would increase readability and allow you to call methods more directly without the need for instantiation of Objects. It mostly depends on if you actually need multiple instances or not. Code is just an example, may contain syntax errors ect.
The reason I wouldn't recommend Abstract class.
Abstract classes are better when you have alot of concrete subclasses/inheritance. Since there isn't much inheritance here its more of a Container relationship rather than an inheritance one. A good analogy might be modeling a zoo. If you want to model all the different types of animals you have, an interface would be better. If you wanted to describe how the animals were related to each other, abstract classes would be better. Your problem has different types of things as the root cause rather than the relation between those two or more things.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Just because you have a single instance doesn't mean that their methods should be static. I would recommend the second option.
– Hongyu Wang
14 mins ago