Sto provando a modellare un sistema esterno in Java e ad eseguire alcuni problemi.
Ho una manciata di tipi correlati che ho mappato insieme attraverso classi astratte (e talvolta concrete se apprezzabili).
In alcuni casi alcune delle sottocategorie si sono rivelate solo implementando un metodo chiamante che ha appena selezionato un URL esterno da utilizzare, mentre lasciava che l'ABC costruisse il payload per esso.
Esempio di seguito in Python (perché non ho Eclipse installato su questa macchina):
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())
Il consumatore dell'API sceglierà quale classe concreta ha bisogno (di solito attraverso DI) e quindi chiama il metodo pubblico doSomething
per inviare i dati all'API esterna e ottenere l'output.
Stiamo anche utilizzando builder che costruiscono le istanze concrete, dal momento che una singola istanza concreta può modellare più tipi di oggetti logicamente diversi e creiamo solo una sottoclasse se c'è una vera differenza.
Sono preoccupato per aver riscontrato alcuni problemi di progettazione qui. Penso che abbiamo eliminato la sostituzione di Liskov nell'esempio precedente (anche se se l'albero di ereditarietà si abbassasse di un livello dovremmo preoccuparcene), ma la chiamata del figlio alla classe genitrice per generare un carico utile è preoccupante così come il bambino che essenzialmente sta configurando il genitore chiamando un URL specifico.