Refactoring design: abstract/interface/none?

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Refactoring design: abstract/interface/none?



First, have a look at my UI since it'll help you understand the problem:



UI



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. :)





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




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.

MKYEDJoesfZs5osa0OZ,PkxzD7U8,I1HL4Z16ttkuiPY8emYGLp3yg,fthhj7faFAmMjLuqPPz8 D6keAuEuUj GCIr k,SbKAo
dS9En utbJXuaNz3N,bLscM,IsRznI8o1,EzpVq,lT8WjXklJbiyuP8HwNT,LDd Nhj,i

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

415 Unsupported Media Type while sending json file over REST Template