I am trying to model an external system in Java and running in to some issues.
I have a handful of related types that I have mapped together through abstract (and sometimes concrete if it made sense) classes.
In a few cases some of the SubClasses turned out to be only implementing a caller method that just picked an external URL to use, while letting the ABC build the payload for it.
Sample below in Python (because I don't have Eclipse installed on this machine):
from abc import ABC,abstractmethod class Parent(ABC): @abstractmethod def callExternal(self): ''' Each concrete child knows which external URL it needs to call ''' pass def doSomething(self): ''' Represents the entry point if this was Java, this would be the public method the rest would probably be protected ''' urlOutput = self.callExternal() return ' '.join(['I am',urlOutput]) def buildPayload(self): ''' Payloads for children are exactly the same In reality we are using builders to set members but the structure of the payload between children is the same ''' return 'some payload' class ChildOne(Parent): def callExternal(self): payload = super(ChildOne,self).buildPayload() apiOutput = 'ChildOne'#hit the api specific to child 1 here self.childOneSpecificMember = apiOutput return ' '.join([payload,apiOutput]) class ChildTwo(Parent): def callExternal(self): payload = super(ChildTwo,self).buildPayload() apiOutput = 'ChildTwo'#hit the api specific to child 2 here return ' '.join([payload, apiOutput]) if __name__ == '__main__': print(ChildOne().doSomething()) print(ChildTwo().doSomething())
The consumer of the API will pick which concrete class it needs (usually through DI) and then call the public
doSomething method to send data to the external API and get the output.
We are also using builders build the concrete instances, since a single concrete instance could model multiple logically different types of objects, and we only create a subclass if there is a real difference.
I am worried I am running in to a few design issues here. I think we sidestepped Liskov Substitution in the above example (though if the inheritance tree went another level down we would have to worry about it), but the child call to the parent class to generate a payload is worrying as well as the child essentially configuring the parent by calling a specific URL.