For my application, I need to use two slightly different algorithms for persisting an entity:
def persistRandomAlias(self, alias):
self.em.persist(alias)
try:
self.em.flush()
except DBALException as e:
if e.previous.code != 23000:
raise e
self.reloadEM()
self.persistRandomAlias(alias)
def persistCustomAlias(self, alias):
self.em.persist(alias)
try:
self.em.flush()
except DBALException as e:
if e.previous.code != 23000:
raise e
self.reloadEM()
existing = self.findByNaturalKey(alias.name)
if existing != alias:
raise DuplicateNameException('The requested name is already taken', e)
The difference between them is in part of the code responsible for exception handling. I thought about putting the common code in one method, with remaining operations passed in a function that would accept exception object, like this:
def persistAlias(self, alias, exHandler):
self.em.persist(alias)
try:
self.em.flush()
except DBALException as e:
if e.previous.code != 23000:
raise e
self.reloadEM()
exHandler(e)
def persistRandomAlias(self, alias):
self.persistAlias(alias, lambda e: self.persistRandomAlias(alias))
def persistCustomAlias(self, alias):
def exHandler(e):
existing = self.findByNaturalKey(alias.name)
if existing != alias:
raise DuplicateNameException('The requested name is already taken', e)
self.persistAlias(alias, exHandler)
However, I'm not sure if it is correct to pass an unused argument to a function.
I have also thought about refactoring common code into an abstract method object class, like this:
def execute(self):
self.em.persist(alias)
try:
self.em.flush()
except DBALException as e:
if e.previous.code != 23000:
raise e
self.reloadEM()
self.e = e
self.handleE()
handleE()
would be implemented in subclasses of the class implementing execute()
method, and it could access exception object, or not, depending on implementation.
Should I choose one of these ideas for dealing with code duplication? Which one is better? Do you suggest a better solution?