0

Currently i got an entity class:

public class Notification {

   private NotificationType type;
   private LocalDateTime sentDate;
   private String message;
   private String imageUrl;
   private String refId;
}

And an enum:

public enum NotificationType {

   INVITATION_TO_GROUP("INVITATION_TO_GROUP"),
   LEAVING_GROUP("LEAVING_GROUP"),
   QUESTION_ANSWERED("QUESTION_ANSWERED"),
   NEW_OWNER("NEW_OWNER");

   private String value;

   NotificationType(String value) {
       this.value = value;
   }

   @JsonValue
   public String getValue() {
       return value;
   }
}

I want to create notifications based on enum value so i created a simple method in my notification service:

public <T> Notification createNotification(NotificationType type, T obj) {

   Notification response = null;
   GroupRequest request;

   switch(type) {
       case INVITATION_TO_GROUP:
           request = ((GroupRequest) obj);
           response =  new Notification(
               NotificationType.INVITATION_TO_GROUP,
               ...
               request.getId().getUser()
           );
           break;
       case LEAVING_GROUP:
           request = ((GroupRequest) obj);
           response = new Notification(
               NotificationType.LEAVING_GROUP,
               ...
               request.getId().getGroup().getOwner()
           );
           break;
       case NEW_OWNER:
           Group group = ((Group) obj);
           response = new Notification(
               NotificationType.NEW_OWNER,
               ...
               group.getOwner()
           );
           break;
       case QUESTION_ANSWERED:
          //??
           break;
       default:
           break;
   }

   return response;
}

As you can see i got one generic parameter for diffrent objects that i use to initialize Notification objects. It works for first 3 enum values but for QUESTION_ANSWERED value besides passing an object like in previous 3 cases i need to pass also a String value and the whole method would look even more ugly than now. I think i need to use Factory desing pattern but i really can't fit which one to use for diffrent number of parameters. Do i need to create simple factory interface with methods like createNotificationForInvitation, createNotificationForQuestionAnswered etc. for each enum value with diffrent parameters and all of them will return Notification objects? How to make it look more pretty? :)

scof93
  • 359
  • 1
  • 4
  • 14
  • 3
    You're using generics badly. You should not be having to cast `obj` to the correct class. You probably want to use [*method overloading*](https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html). – Michael Nov 07 '17 at 10:58
  • Ok so i can remove `createNotification` method from notification service and then i should create an interface with 4 methods for each enum value that takes specific `obj` types? Also for this interface an implementation that would basicly do the same returning `Notification` objects? – scof93 Nov 07 '17 at 11:08
  • Possible duplicate of [Factory in Java when concrete objects take different constructor parameters](https://stackoverflow.com/questions/13885836/factory-in-java-when-concrete-objects-take-different-constructor-parameters) – Fuhrmanator Nov 10 '17 at 16:18
  • @scof93 You must accept the answer if it solved your problem to make it as an authenticated answer for future readers of your post. Read this https://stackoverflow.com/help/someone-answers – XING May 29 '18 at 10:23

1 Answers1

1

I am skeptical on whether Factory pattern is good choice here, since besides the type you switch on, you also pass a bunch of varying parameters for each type. It shows when having to cast the request type, set parameters and pass in the constructor for each case.

I would suggest polymorphism and as Michael suggested overload your constructor.

Let's say you have a base class BaseRequest and then subclasses such as InvitationRequest, NewOwnerRequest, etc.

Then your Notification class would look like:

public class Notification {

    public Notification(InvitationRequest request) { 
        //your setting up here 
    }

    public Notification(NewOwnerRequest request) {
       ... 
    }

    public Notification(QuestionAnswered request) {
        //QuestionAnswered has the String value you wanted 
    }

}
martidis
  • 2,897
  • 1
  • 11
  • 13