I have a simplified design as the following (basically a bunch of handlers to handle 2 different types of request: EventRequest and SpeechRequest). Below is the pseudocode:
class SpeechRequest {sessionId: String; slot: String}
class EventRequest {sessionId: String; event: String}
class SpeechRequestHandler;
class EventRequestHandler;
class SpeechRequestHandler[A/B/C] extends SpeechRequestHandler {
- handle(request: SpeechRequest) {
doSt(request.slot)
}
}
class EventRequestHandler[A/B/C] extends EventRequestHandler {
- handle(request: EventRequest) {
doSt(request.event)
}
}
There is 2 different dispatchers to find appropriate handlers for each types of requests and forward them to handlers to handle:
class SpeechDispatcher {
- handle(request: SpeechRequest) {
handler: SpeechRequestHandler = findHandlerToHandle(request);
handler.handle(request);
}
}
class EventDispatcher {
- handle(request: EventRequest) {
handler: EventRequestHandler = findHandlerToHandle(request);
handler.handle(request);
}
}
Now, i want to refactor and create a base/common classes. Naturally, I came up with this:
class Request {sessionId: String}
class SpeechRequest extends Request {slot: String}
class EventRequest extends Request {event: String}
class RequestHandler {
- canHandleRequest(Request): bool
- handle(Request)
}
class SpeechRequestHandler extends RequestHandler {
- canHandleRequest(request: Request): bool = request instanceof SpeechRequest
}
class EventRequestHandler extends RequestHandler {
- canHandleRequest(request: Request): bool = request instanceof EventRequest
}
class SpeechRequestHandler[A/B/C] extends SpeechRequestHandler {
- handle(Request: request) {
//need to cast to specific type to extract a certain fields to do some operation
//!! I feel something is not right because of that
speechRequest:SpeechRequest = (SpeechRequest)request;
doSt(speechRequest.slot)
//other operation can work with base Request object; so it's OK
}
}
class EventRequestHandler[A/B/C] extends EventRequestHandler {
- handle(Request: request) {
eventRequest:EventRequest = (EventRequest)request;
doSt(eventRequest.event)
//other operation can work with base Request object; so it's OK
}
}
The fact that for all SpeechRequestHandler[A/B/C]:handle functions, I now need to cast the Request object to (SpeechRequest) object specifically: speechRequest:SpeechRequest = (SpeechRequest)request;
I feel that there is flaw in my design. If every SpeechRequestHandler I need to cast the object to (SpeechRequest) so that I can do something with those info, does it means that it doesn't make sense to refactor a base class in this case ?
Please could you suggest a better way or a design pattern to handle this cleanly.
Thank you.
Aucun commentaire:
Enregistrer un commentaire