There is a problem in designing a class system.

There is an abstract class "Member", which can send information in the form of an abstract class "Request" to other "Participants". There is also a hierarchy of heirs from the "Participant" and a hierarchy of heirs from the "Request", each with its own behavior. The problem is that the exchange of requests is implemented at the level of the base class “Member”, which knows only about the methods and properties of the base class “Request”. Consequently, realizing the heirs from the "Participant", and wanting to gain access to the additional fields of the heirs of the "Request", you will have to deal with type casting, which indicates that the model is flawed.

How to organize it more gently?

  • one
    observer, no? - Barton
  • Why don't you want to implement a publisher-subscriber pattern? - Alexey Anufriev
  • Firstly, all the “Participants” themselves choose a specific recipient of the “Request”, and secondly, the “Request” must be expandable. Those. I can create a "Member" with a unique behavior pattern and define a new type of "Request" with additional properties that new types of "Members" should be able to handle. What, I don't understand how the observer model can help here. - nrw
  • Great question. Remarkably highlights a bunch of problems that arise from the developer, if desired, to strictly observe the rules of the PLO. - avp

1 answer 1

Having a request behavior is strange. Obviously, your hierarchy does not make sense, because heir classes have interfaces that are incompatible with the base class interface. Those. The principle of substitution is not fully respected. Maybe it makes sense for the requests to leave a sign (a property of this class or its type) that determines the type of the request, and put the behavior into separate classes that know what to do with a specific type of request (let's call them handlers). Handlers will have the same interface (the handle method), but different behavior. Participants need to redirect requests to the correct handlers according to their type.

And do not play with inheritance. Most often this is the wrong attitude.

  • The request has no behavior. The heirs of the request only have additional properties (i.e., additional information is transmitted). Now the receiver has to check what class instance is the incoming request and then do a type conversion to get access to additional properties. This is certainly not deadly, but somehow far from the PLO. - nrw
  • one
    @nrw in this setting, you do not solve the problem without casting. Once again I will say that inheritance here only hinders. Try to present specific properties of requests in a more general form. For example, in an HTTP request there are parameters, headers and body, and all handlers will work with these properties, but each in its own way for different requests. - a_gura
  • Prefilling the request class with fields for reserve for the future, this is a very dirty code. And in any case in the future there may be a situation when these fields are not enough. And with the cast, the system remains extensible and does not require alteration of the base classes, so I prefer the latter. - nrw
  • @nrw, do you have a thoughtful scheme of how it will look in the final? I can not just come up with an expanding query, even kill. In extreme cases, you can simply attach the getExtraData() method and pull it when necessary. - etki
  • Although of course you can still make the property's request class as a dynamic array of named properties. Then no casting is necessary, but in my opinion it is even more perverted :) - nrw