3

I have the following tree currently to be implemented in Java. enter image description here

My problems are the following:

  • How can I go about addressing the fact Admin needs to have all tier 4 logic from both branches of the tree since I cannot inherit all 5 of said classes?
  • How can I refactor the tree to reflect the fact that outside tier 4 and Anonymous class, the rest shouldnt be instatiated since I cant have multiple abstracts extend each all the way down to tier 4 due to Java's restrictions? ( I can set their constructor to private and be done with this but that feels kind of a cheap hack to avoid some design flaw in my tree).
1
  • 1
    I am favoriting this for future reference (arguments with coworkers) as it is a a clear example of how you can do everything properly, but still run into problems with inheritance. Commented Jun 19, 2017 at 14:25

2 Answers 2

3

The problem here is that you've been mislead to express these kind of relationships with inheritance. You have not done anything wrong, this problem typifies the problems with inheritance and why it is generally not favorable to composition.

Favor composition to inheritance

There are many approaches to this issue, but the following is what stands out to me as the simplest:

First, you have a User class, unlike in your hierarchy, this represents a system user, and that is it.

Obviously, these are quick layouts, replace the properties with getters, setters, ect.

interface HasSessionId
{ 
    ID;
}

interface CanCheckPermission
{
    HasPermissionTo(permission); 
}

class AnnoUser implements CanCheckPermission, HasSessionId
{
    ID;
}


class RegisterUser implements CanCheckPermission, HasSessionId
{
     ID;  
     UserName;
     FirstName;
     LastName;
     Login; //Sometimes it is helpful to separate the login into a a different concept to make impersonation easier, ect, you may or may not need this in your system.
}

Next, you have your system roles. This is a completely different thing than a user. Any common behaviors or properties they may have are in an interface. Interfaces implement only minimal functionality and should not be viewed as a base class without implementation. They only express something the System roll can do.

interface IsAUser
{
    User;
}

interface CanBuy
{
     Buy(product);
}

Our individual system rolls can now implement these interfaces to express their available functions, and are free to do things differently if they want, but they may have common behavior we want to leverage, which is where the buying utility comes in.

class BuyingUtility
{
   //static stuff is generally bad, but this is the closest Java has to functions. Avoid static fields as much as possible
   static Buy(product, IsAUser) { /*buy logic*/ }
}

class Admin implements IsAUser, CanBuy, CanSell
{
     User;
     Buy(product)
     {
           BuyingUtility.Buy(product, this);
     }
}

class BuyerManager implements IsAUser, CanBuy
{
     User;
     Buy(product)
     {
           BuyingUtility.Buy(product, this);
     }
}
2
  • 1
    Accepted this answer as a good use of what the other answer proposed in terms of the problem in hand. Thanks.
    – Leon
    Commented Jun 19, 2017 at 12:45
  • Yes, Kilian's answer was correct, but did not offer a demonstrable solution to your problem or explain the terms used. Commented Jun 19, 2017 at 14:16
2

The fact that you have created several classes whose functionality is sometimes mutually exclusive (Buyer vs. Seller) and sometimes cumulative (Admin) proves that (when working with Java) these cannot all be classes. Therefore, you have to find a different, somewhat more complex model to represent these different entities.

A popular choice is to create classes which hold only the varying functionality and compose your actual entity-representing objects from these. Searching for mix-ins, decorators, traits or facets will point you towards documentation of various well-established patterns for this purpose.

1
  • Those were some good reads suggested ! Ty
    – Leon
    Commented Jun 19, 2017 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.