Design pattern question
Eric Brunel
eric.brunel at pragmadev.com
Wed Aug 21 04:19:23 EDT 2002
Karl Schmid wrote:
> Hi,
>
> I would like to separate an abstraction from its implementation. I think
> this is called the Bridge pattern by Gamma et al. (or at least it is a
> part of a bridge pattern).
>
> In particular, I would like to assemble a set of DNA sequences and have
> the option to chose among different assembly algorithms. I am not sure
> what the best way to do this would be:
>
>
> class SequenceAssembler:
>
> def __init__(self,assembler_type):
>
> if assembler_type == 'cap3':
> # What should I do here?
> elif assembler_type == 'phrap':
> # What should I do here?
>
> def save_sequences():
> pass
>
> class Cap3Assembler(SequenceAssembler):
>
> def run_assembler():
> # Cap3 specific instructions
> pass
>
> class PhrapAssembler(SequenceAssembler):
>
> def run_assembler():
> # Phrap specific instructions
> pass
>
> Now I would like to instantiate the abstract class, but to obtain an
> instance of either the Cap3Assembler or PhrapAssembler class depending on
> the assembler_type variable.
>
>>>> assembler = SequenceAssembler(assembler_type)
>
> Is this possible?
AFAIK, there's not a single OO language that allows to do this this way. In
Python, I saw once that it's possible to assign a new value to the
__class__ attribute of an object, so *theoretically*, Python object can
dynamically change their class. But this attribute is certainly not meant
to be changed and doing so may certainly have unpredictable results. If
anyone knows better, please let me know...
The solution I'd adopt is to use another design pattern: the abstract
factory:
class SequenceAssembler:
...
class Cap3Assembler(SequenceAssembler):
def run_assembler(self):
...
class PhrapAssembler(SequenceAssembler):
def run_assembler(self):
...
class SequenceAssemblerFactory:
type2Class = {
'Cap3' : Cap3Assembler,
'Phrap' : PhrapAssembler
}
def newSequencerAssembler(self, assemblerType):
return SequenceAssemblerFactory.type2Class()
fact = SequenceAssemblerFactory()
assembler = fact.newSequencerAssembler(assembler_type)
If you need the factory in many places, use yet another design pattern:
singleton class:
class SequenceAssemblerFactory:
type2Class = {
'Cap3' : Cap3Assembler,
'Phrap' : PhrapAssembler
}
theInstance = None
def __init__(self):
SequenceAssemblerFactory.theInstance = self
def newSequencerAssembler(self, assemblerType):
return SequenceAssemblerFactory.type2Class()
SequenceAssemblerFactory()
assembler = \
SequenceAssemblerFactory.theInstance.newSequencerAssembler(assembler_type)
HTH
--
- Eric Brunel <eric.brunel at pragmadev.com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
More information about the Python-list
mailing list