Home > front end >  Inheritance and Composition problem in class Diagram
Inheritance and Composition problem in class Diagram

Time:11-15

So there is a small scenario from a big system. It is a Car Booking System where User class needs to be more cohesive. In my Initial Scenario, My User class was catering User operations, User Verification, User Profile and had a different class for Admin.

  1. team was instructed to make User class more cohesive
  2. Break User into UserProfile and make the Verification Process separate from this class
  3. As Admin is also a User so you can inherit Admin from User.

Inheritance performed

  1. Admin will inherit the UserProfile part but the Verification Process will only be applicable to customer.

now this is where I got stuck and I don't know how the User Verification can only connect to User which is parent class but not goes to the child class. as Admin don't need any verification process.

My suggested solution is:

enter image description here but I am very unsure about inheriting two users and specially when the Customer class have all methods of Verification, that means Class name dont represent it's actual functionality.

CodePudding user response:

How is the design?

Your suggested solution is an interesting start. It separates:

  • the User, which exposes operations that could be driven by some user interface,
  • the UserProfile, which manages the personal information of a user,
  • the user's role, i.e. Customer role or Admin, which provides role specific behaviors and responsibilities.

The main weakness of this design is an insufficient separation of concerns.

Separating user-interface behavior from internal behavior

Some of your classes seem to be domain classes but seem at the same time to be supposed to have user-interface responsibilities (e.g. UserProfile and editProfile() )

If this is a toy project with a command line interface, it's ok. But a safer approach would be to focus on classes that could be invoked by a user interface with some data, but without having itself any user-interface responsibility (e.g. editProfile() would be replaced with getters that would allow a form to populate content, and setters, to update the class once the form is validated).

Separate responsibilities using the decorator pattern

Customer and Admin both add different sets of responsibilities and attributes to the user. Instead of using inheritance, you could prefer composition and use the decorator pattern: Customer and Admin would then be decorators of User, where Customer would add the responsibility to manage the verification.

A slight improvement would be to make the distinction between a User and a UserRole. A UserRole would be an abstract class, and Customer and Admin would be decorators of the role.

This would allow you to easily introduce new roles (Supplier, Auditor, ...) without changing the design of the users. You could even allow multiple roles at the same time if you change multiplicity on the UserRole side of the composition.

Implement policies with the strategy pattern

Another problem that you have introduced in your solution is that the UserVerification was merged part into UserProfile and part into Customer. This is not a sound separation of concerns.

A better approach is to make UserVerification a strategy of a UserRole. You could decide to set the strategy in the construction of each specific UserRole. The Admin could then use a light strategy that considers a user as always verified without further steps.

Some more (unrelated) thoughts

Never ever store passwords. The interaction should not be: "ask password, then get profile password and verify if they are the same", but "ask password, compute a password hash code, check if the hash code matches".

In this regard, you may consider extracting password related properties and operations into a separate class. This would allow to change user authentication strategies exists and opt of OS authentication, 2FA authentication, single sign on, and other authentication approaches.

  • Related