Java Generic Interfaces with multiple implementations
I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
@Autowired @Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
@Autowired @Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
java generics interface
add a comment |
I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
@Autowired @Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
@Autowired @Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
java generics interface
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
1
Don't use == withStrings: use aswitchstatement or.equals()
– Maurice Perry
Nov 16 '18 at 6:03
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12
add a comment |
I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
@Autowired @Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
@Autowired @Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
java generics interface
I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
@Autowired @Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
@Autowired @Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
java generics interface
java generics interface
edited Nov 16 '18 at 6:22
Muneer Y
asked Nov 13 '18 at 8:08
Muneer YMuneer Y
213
213
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
1
Don't use == withStrings: use aswitchstatement or.equals()
– Maurice Perry
Nov 16 '18 at 6:03
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12
add a comment |
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
1
Don't use == withStrings: use aswitchstatement or.equals()
– Maurice Perry
Nov 16 '18 at 6:03
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
1
1
Don't use == with
Strings: use a switch statement or .equals()– Maurice Perry
Nov 16 '18 at 6:03
Don't use == with
Strings: use a switch statement or .equals()– Maurice Perry
Nov 16 '18 at 6:03
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12
add a comment |
2 Answers
2
active
oldest
votes
How about this?
- No need of any if conditions.
- Later if someone does add another implementation of BaseTask they don't have to change any other code.
- Also I recommend changing "atype" to Enum and using
Map<EnumTask, ? extends BaseTask> serviceMap;instead of String.
Your final invocation of Tasks can be without any checks
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require aTaskServiceManager
– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
|
show 2 more comments
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276456%2fjava-generic-interfaces-with-multiple-implementations%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
How about this?
- No need of any if conditions.
- Later if someone does add another implementation of BaseTask they don't have to change any other code.
- Also I recommend changing "atype" to Enum and using
Map<EnumTask, ? extends BaseTask> serviceMap;instead of String.
Your final invocation of Tasks can be without any checks
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require aTaskServiceManager
– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
|
show 2 more comments
How about this?
- No need of any if conditions.
- Later if someone does add another implementation of BaseTask they don't have to change any other code.
- Also I recommend changing "atype" to Enum and using
Map<EnumTask, ? extends BaseTask> serviceMap;instead of String.
Your final invocation of Tasks can be without any checks
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require aTaskServiceManager
– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
|
show 2 more comments
How about this?
- No need of any if conditions.
- Later if someone does add another implementation of BaseTask they don't have to change any other code.
- Also I recommend changing "atype" to Enum and using
Map<EnumTask, ? extends BaseTask> serviceMap;instead of String.
Your final invocation of Tasks can be without any checks
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
How about this?
- No need of any if conditions.
- Later if someone does add another implementation of BaseTask they don't have to change any other code.
- Also I recommend changing "atype" to Enum and using
Map<EnumTask, ? extends BaseTask> serviceMap;instead of String.
Your final invocation of Tasks can be without any checks
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
edited Nov 13 '18 at 9:13
answered Nov 13 '18 at 8:30
Bandi KishoreBandi Kishore
3,5311832
3,5311832
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require aTaskServiceManager
– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
|
show 2 more comments
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require aTaskServiceManager
– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
I doubt if it's OK that a task would know about its manager
– Andrew Tobilko
Nov 13 '18 at 8:39
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
@AndrewTobilko Edited it, the logic can be only inside the Base Class. That way the child Tasks will never have to know about the manager. But Yes, BaseTask will still know about it. That should still be fine as Manager class here is just a friend or helper type of class to keep track of the different tasks which are running.
– Bandi Kishore
Nov 13 '18 at 8:49
Children still would require a
TaskServiceManager– Andrew Tobilko
Nov 13 '18 at 8:56
Children still would require a
TaskServiceManager– Andrew Tobilko
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
No change, the same way a Service class was instantiated. Since its spring, you'll only have to annotate it with @Service (Added it to the answer). Basically a SIngleton class and inject the Manager class into BaseTask. If using Spring, we could directly Inject the Manager into Base class without having to send it from child. But wouldn't work if there is no DI framework. Any suggestions on how to make it better?
– Bandi Kishore
Nov 13 '18 at 8:56
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
Tasks aren't beans, they are extracted from an order
– Andrew Tobilko
Nov 13 '18 at 8:57
|
show 2 more comments
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
add a comment |
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
add a comment |
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
edited Nov 16 '18 at 6:37
answered Nov 16 '18 at 6:23
Maurice PerryMaurice Perry
5,5562516
5,5562516
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276456%2fjava-generic-interfaces-with-multiple-implementations%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
this code doesn't seem to compile
– Andrew Tobilko
Nov 13 '18 at 9:14
1
Don't use == with
Strings: use aswitchstatement or.equals()– Maurice Perry
Nov 16 '18 at 6:03
@AndrewTobilko I just wrote pseudo code to be able to ask my question.
– Muneer Y
Nov 16 '18 at 6:12
@MauricePerry I update my code basing on your comment.
– Muneer Y
Nov 16 '18 at 6:12