Doubt on layered architecture

Hello,

I’m trying to organize my application in a 3 layer achitecture, as suggested in the book of Vaadin. What I’m doing is:

  • First layer for UI components
  • Second layer for beans
  • Third layer for data management (communication with the database)

I am creating a specific package for each of these layers.
The principle described in the book is that each layer can be dependent on the next one, but not the other way aoound. So layer 1 can depend on layer 2, but layer 2 should not depend on layer 1.

Now, I have a DBManager class which takes care of all DB queries, and holds the connection to the DB. This class is included in the third layer, as it is database related.

And taking the user management in my application as an example, I have created a User bean in the second layer, and a userData class in the third layer. The userData class handles all DB communications for user related stuff (insert a new user, retrieve user data, etc…). So, the idea is for the User bean to have a userData object as a variable. And the userData, in turn, makes use of the DBManager class described above, as it is the one holding the connection to the DB.

My problem is that I am not able to achieve this architecture while maintaining the layer principle above. My DBManager object must be common to all, because it holds the DB connection, So I am creating a specific instance in the main UI, which will be shared across the application

//FIRST layer
public class MainUI extends UI {
    DBManager db = new DBManager();
    
    UserBean user = new UserBean();
}

//SECOND layer
public class UserBean{
    UserData userData;
    
    public UserBean(){
        userData = new userData();
    }
}

Now, in the userData clas of the third layer, I would need to use the particular db variable of the particular UI instance, like:

[code]
//THIRD layer
public class userData{
DBManager db;

public userData(){
    db = ((MainUI)getUI()).db
}

}
[/code]But since the userData class is not a component (nor is the UserBean), I actually do not have the getUI() method, so I need to pass the UI as an argument from the first layer. It would have to be something like this:

[code]
//FIRST layer
public class MainUI extends UI {
DBManager db = new DBManager();

UserBean user = new UserBean(getUI());

}

//SECOND layer
public class UserBean{
UserData userData;

public UserBean(UI ui){
    userData = new userData(ui.db);
}

}

//THIRD layer
public class userData{
DBManager db;

public userData(db){
    this.db = db;
}

}
[/code]The problem with this is that I am braking the layer principle, because the second layer is actually dependent on the first layer, and the third one depends on the second one. And this would happen with every bean I create with its correspondent data class (for example, carBean and its carData, etc.). So this leads me to think that perhaps this is not the best approach. Is there a prferred way to organize this?

Thank you very much.

Hi,

Your UI implementation already breakes the layered architecture you want to follow.
MainUI
is in the presentation layer hence it cannot have any reference to classes in the persistence layer. But it does,
MainUI
has a reference to
DBManager
which is in the persistence layer. So the first thing you need to do is to remove that reference from there.


MainUI
(and any class in the presentation layer) should only use classes in the domain layer (the one you called “beans”). The domain layer contains business related logic and can be invoked directly by UI components. All persistence logic should be placed in the third layer: The persistence layer. The domain layer can use the persistence layer directly.

I would suggest you do something like this:

// presentation layer (knows nothing about persistence logic, but uses the domain layer)
public class MainUI {
    private UserService userService = new UserService();
    
    private void someMethod() {
        userService.registerNewUser(name, password);
    }
    ...
}


// domain layer (knows nothing about presentation layer but uses the persistence layer)
public class UserService {
    private UserData userData = UserData.getInstance();

    public void registerNewUser(String name, String password) {
        User newUser = new User(name, password);
        userData.persist(newUser);
    }
    ... implement getInstance() using the Singleton pattern
}


// persistence layer (knows nothing about presentation layer or domain layer)
public class UserData { // I would call this UserRepository instead
    private DBManager dbManager = DBManager.getInstance();

    private void persist(User user) {
        ... use the dbManager instance to do whatever you need in order to persist the user
    }
    ... implement getInstance() using the Singleton pattern
}

public class DBManager {
    ... implement getInstance() using the Singleton pattern
    ... implement required methods using the selected persistence technology
}

Where to put the
User
class? I would say the
User
class is just a DTO (Data Transfer Object) so it could be common to several layers. Think of DTOs as if they where
String
s,
Long
s, etc. They just carry data.

All this would be implemented a bit different if you are using, for example, Domain-Driven Design, or if you are using a framework such as Spring. But the idea remains the same.

Hope I didn’t confused you more than helped you :wink:

Hi Alejandro,

Thank you very much for your detailed answer.
No, you didn’t confuse me. I actually didn’t know about the Singleton pattern, but after a quick google on that, your explanation was quite clear, as well as instructive.

Can I just ask for one further piece of advice? The application requires a funtionality to search for other users. So, based on the implementation you suggest, would you advice to include that functionality in the same UserService class, or do you feel it’s better to implement that in a different object, and keep the UserService for handling single user logic?
Mi idea is to have a
findUsers
method with a search String parameter in the
UserService
class, which in turn calls a
search
method in the
UserData
(or UserRepository) class, that returns a
User
object collection.

Do you think that’s alright? Or do you think that’s kind of “stressing” the application logic? For example, I don’t feel very comfortable with the fact that the
findUsers
method would actually just be an intermediary between layers. I mean, it would simply pass the search String parameter (input by the user) from the presentation layer to the persistence layer, and then the
User
collection from the persistence layer back to the presentation layer in order to display it in a Table or Grid. But it doesn’t actually implement any logic in itself.

Thanks again for your help.