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.