generics - java open closed principle for multiple services -
let's wanted define interface represents call remote service.
both services have different request , response
public interface executesservice<t,s> { public t executefirstservice(s obj); public t executesecondservice(s obj); public t executethirdservice(s obj); public t executefourthservice(s obj); }
now, let's see implementation
public class servicea implements executesservice<response1,request1> { public response1 executefirstservice(request1 obj) { //this service call should not executed class throw new unsupportedoperationexception("this method should not called class"); } public response1 executesecondservice(request1 obj) { //execute service } public response1 executethirdservice(request1 obj) { //execute service } public response1 executefourthservice(request1 obj) { //execute service } } public class serviceb implements executesservice<response2,request2> { public response1 executefirstservice(request1 obj) { //execute service } public response1 executesecondservice(request1 obj) { //this service call should not executed class throw new unsupportedoperationexception("this method should not called class"); } public response1 executethirdservice(request1 obj) { //this service call should not executed class throw new unsupportedoperationexception("this method should not called class"); } public response1 executefourthservice(request1 obj) { //execute service } }
in other class depending on value in request creating instance of either servicea
or serviceb
i have questions regarding above:
is use of generic interface executesservice<t,s>
in case want provide subclasses require different request
, response
.
how can above better?
basically, current design violates open closed principle i.e., if wanted add executefifthservice()
method servicea
, serviceb
etc.. classes.
it not idea update of service a, b, etc.. classes, in simple words, classes should open extension closed modification.
rather, can refer below approach:
executesservice interface:
public interface executesservice<t,s> { public t executeservice(s obj); }
servicea class:
public class servicea implements executesservice<response1,request1> { list<class> supportedlistofservices = new arraylist<>(); //load list of classnames supported servicea during startup properties public response1 executeservice(request1 request1, service service) { if(!list.contains(service.class)) { throw new unsupportedoperationexception("this method should not called class"); } else { return service.execute(request1); } } }
similarly, can implement serviceb
well.
service interface:
public interface service<t,s> { public t execute(s s); }
firstservice class:
public class firstservice implements service<request1,response1> { public response1 execute(request1 req); }
similarly, need implement secondservice
, thirdservice
, etc.. well.
so, in approach, passing service
(to called, firstservice
or secondservice
, etc..) @ runtime , servicea
validates whether in supportedlistofservices
, if not throws unsupportedoperationexception
.
the important point here don't need update of existing services adding new functionality (unlike design need add executefifthservice()
in servicea
, b
, etc..), rather need add 1 more class called fifthservice
, pass it.
Comments
Post a Comment