Flexibility in using feature classes

public interface iUserInfo { string getUserName(int userId); string getUserAge(string username); } public class UserDb implements iUserInfo { string getUserName(int userId) { //code to retrieve user info from the database } } public class UserTxtFile implements iUserInfo { string getUserName(int userId) { //code to retrieve user info from the plain text file } } public class UserManager() { private iUserInfo userInfo; public string retrieveUserData(string userName) { return userInfo.getUserAge(userName); } } 

My professor says

"the above user manager class has a reference variable of type iUserInfo, therefore, if this link is provided by the factory method or any other means, the code of the manager class will be the same regardless of which implementation is provided.

"This approach maximizes flexibility if some implementations need to be changed during the software development process, as higher level layers will not be affected at all."

I need to understand two things; maximizing flexibility and factory method.

The last one could probably be something like this

 public class UserManager() { private iUserInfo userInfo; private UserTxtFile uTxtFile; private UserDb uDB; public iUserInfo GetUserInfoObjFactory(bool dbOrTxt) { return dbOrTxt? uTxtFile:uDB; } public string retrieveUserData(string userName) { return userInfo.getUserAge(userName); } } 

and during the lecture, I kind of dreamed about other things, and now I can’t understand what exactly this means? I would like to understand in a little more detail, just in case some interviewers may attack me with more open questions that I’m not sure how to answer.

Could you also add some code that breaks the above source in the example when high-level levels are affected? Thank you very much.

[ Refresh ] I also find an answer such as “we need an interface to group common methods” is actually not very convincing. An unambiguous base class also helps. For example, the Fly behavior of two objects {Penguin vs Bird}. I can’t just tell the interviewer that IFly is needed at all. Even when I have millions of different objects that need Fly, I can always implement every Fly for each of them. Because I still need to do this in the implementation classes, even when I design IFly. Could you offer more detailed examples or explain how the interface becomes mandatory?

+4
source share
3 answers

About the need to use interfaces.

Suppose you need to implement an airport manager. He interacts with an object in the airport space, giving them commands regarding their position and situation in the air. This set of commands is well defined and does not depend on the type of object in space. The dispatcher must know the position, he must be able to authorize the landing, refuse to land, delay the landing and issue a course correction of the emergency course. In order for this to be implemented and maintained as easily as possible, we define some kind of interface that we implement in all “aircraft”.

Then we can create an AirportDispatcher that will work with many objects that implement our interface in a common way, not knowing how it is implemented (helicopters can wait in place, but planes must walk while waiting) or even the type of aircraft. All you need to know is that it flies, and it can obey your commands.

Please note that this is not an interface from the point of view of Java, it is just a contract, the way we implement it depends only on the language capabilities. Dynamic or duck languages ​​can do this without any syntactic restrictions, while static typed languages ​​will require additional work.

Interfaces and abstract classes appear. The main difference between an interface and an abstract class is that there can be several interfaces for one object, but only one abstract class (this is not the way it is in all languages, but it is a common denominator). In addition, an interface cannot contain an implementation, while an abstract class can.

+1
source

I will change your code a bit to explain

Why flexibility?

Here is a snippet of code on your system that will print the username. What else, let the image be not only one, but also hundreds of code fragments that use UserDb directly, and they are distributed throughout your system.

 public void printUserName(String userId) { UserDb db = getUserDb(); System.out.println(db.getUserName(userId)); } 

Now, if we want to get user information from a text file? The only way to do this is to change all the code that UserDb uses in UserTextFile . This will take a lot of time, and it can easily introduce errors, because we can accidentally change what should not be.

We call these codes UserDb Coupling .

So, we have a UserManager to solve this problem.

 public class UserManager { private UserDb db; public UserManager(UserDb db) { this db = db; } public String getUserName(String userId) { // return user name using UserDb } } 

If all codes in our system use UserManager as a way to get the username. When we want to switch to a text file, all we can do is change the code inside the UserManager .

But, in the real world of coding, UserManager may not be so simple, they may also have other responsibilities, such as checking input before the request. We can still introduce errors.

That is why we need another layer to remove this connection once for all.

Here is the interface

 public interface iUserInfo { public String getUserName(int userId); public String getUserAge(string username); } 

... and we make the UserManager dependent on iUserInfo

 public class UserManager { private iUserInfo info; public UserManager(iUserInfo info) { this info = info; } public String getUserName(String userId) { // return user name using info } } 

Now that we want to change UserDb to UserTextFile , all we do is write a new concrete iUserInfo class. UserManager will never notice, because the dose does not need implementation details.

The less we modified the code, the less chance of errors. This is the reason we want such flexibility.

This method is called Inversion of Control .


Factory method?

Factory method is one of the design patterns associated with creating an object. Check this question for more information.

Factory, Abstract Factory and Factory Method

The reason your profession mentions the Factory method is because this template is used to hide knowledge of creating objects, iUserInfo in this case, from another class, which means that this method / class is the only code associated with a particular class .

In this way, we can minimize the impact of changes to the iUserInfo implementation iUserInfo

Interface vs Abstract class?

The interface does all your specific work class without extending it. This is good because in Java you can only inherit one class.

On the other hand, an abstract class simplifies working with common code that is used between different implementations.

You can check this question in more detail Interface vs Base Class

+1
source

Your professor lecture means loose communication , and the example relates to Bridge PATTERN .

More details:

The UserManager class must process data that applies business logic and rules, save and retrieve it. This class only needs to know that it needs to store and retrieve data in any place, but is not responsible for the dirty work. Instead, you will have an object, an iUserInfo instance, that will handle saving and retrieving data. How will this object do this work? This does not apply to the UserManager class. This is a loose clutch.

Now, why should there be an interface / abstract class that handles this job? Since you can have different data sources: text files, xml files, relational database, in-memory database, external device, etc. Your UserManager class UserManager not directly access the data source handler, and another class will provide this exact implementation. In this case, you should use an abstraction, which is processed by an abstract class or interface. An abstract class and interface is a contract that sets up methods that a client can use, but not necessarily an implementation of methods. How it works? Consider an example:

 public interface iUserInfo { //the client (any class that uses the interface) knows that can get the UserName //and the UserAge, it doesn't need to know how... string getUserName(int userId); string getUserAge(string username); } public class UserDb implements iUserInfo { string getUserName(int userId) { //this implementation will connect to database to get the data } } public class UserTxtFile implements iUserInfo { string getUserName(int userId) { //this implementation will read from a text file to get the data } } 

Currently, the UserDb and UserTxtFile will handle the dirty work. Now your UserManager can take a breath because it does not need to know where the data will be stored. But there is another question: what implementation should UserManager use to retrieve data?

The factory method is an implementation of Factory. The method template , which says that the client does not need to know which implementation should be used, instead, the factory will make a decision based on configurations or other business rules. This means that the UserManager class can calm down because it does not need to determine access to the implementation! That sounds good? Now, for example, there is a simple method that acts like a factory method

 //it will return the iUserInfo implementation based in a boolean variable //this could become more complex depending on the rules, like retrieving the boolean //value from a configuration file public iUserInfo GetUserInfoObjFactory(bool dbOrTxt) { return dbOrTxt? uTxtFile:uDB; } 

Additional Information:

0
source

All Articles