Code design problem

M

Marco Nawijn

Hello,

I have a hard time figuring out an elegant and efficient design for
the following problem.

I am working on automation of structural design problems. In the
majority of cases, this boils down to executing programs in batch in
one or more loops. The scripts to control the execution differ from
fortran to bash to python and so on. Most of them are ad hoc and what
I call 'throw away scripts'. In order to improve the situation I would
like to develop a Python module that supports the execution of
external programs. Ideally I would like to make running locally or
remote trivial for the users of the module. As an example, I would
like the following (pseudo)-code to work:

app = Application('patran') # Run on local
machine
app.start(args)


app = Application('patran', host='myhost') # Run on remote machine
app.start(args)

The problem I face is that the implementation of the application class
is completely
different for the local and remote case. The local case is a
straightforward implemenation using the subprocess module, the remote
case is a CORBA implementation. Somehow I would like to switch from
implementation class at runtime depending on whether or not the host
parameter is specified or not.

The Application, local implementation and remote implementation all
have the same interface, so a possibility might be something like the
following:

class Interface(object):
.....
def start(self): pass
def stop(self): pass

class LocalImplementation(Interface):
.....

class GlobalImplementation(CorbaGlobalImplementation, Interface):
.....


class Application(Interface):

def __init__(self, program, host=None):
....
if host:
self.__impl = LocalImplementation(program)
else:
self.__impl = GlobalImplementation(program, host)

# Forward all methods to the implementation class
def start(self):
self.__impl.start()

def stop(self):
self.__impl.stop()


To me forwarding each call in the Application class looks a little bit
redundant and I would like to get rid of it. Does anyone have any
comments or suggestions? Can metaclass programming come to rescue?

Kind regards,


Marco Nawijn
 
S

Sion Arrowsmith

Marco Nawijn said:
I have a hard time figuring out an elegant and efficient design for
the following problem.

What you want is known as the factory pattern.
[ ... ] I would
like the following (pseudo)-code to work:

app = Application('patran') # Run on local machine
app.start(args)

app = Application('patran', host='myhost') # Run on remote machine
app.start(args)

The Application, local implementation and remote implementation all
have the same interface, so a possibility might be something like the
following:

class Interface(object):
.....
def start(self): pass
def stop(self): pass

You don't need an abstract interface like this in Python. Duck-
typing will take care of it for you. On the other hand, if you
do have common code between the local and global implementations,
it makes sense to share it in a base class. You might then want
to consider defining the methods which must be overridden as

def start(self): raise NotImplementedError
etc.

Given:
class LocalImplementation(Interface):
.....

class GlobalImplementation(CorbaGlobalImplementation, Interface):
.....

with suitable start and stop methods defined, all you need is
an Application factory function:

def Application(program, host=None):
if host is None:
return LocalImplementation(program)
return GlobalImplementation(program, host)
 
M

Marshall T. Vandegrift

Marco Nawijn said:
The problem I face is that the implementation of the application class
is completely different for the local and remote case. The local case
is a straightforward implemenation using the subprocess module, the
remote case is a CORBA implementation. Somehow I would like to switch
from implementation class at runtime depending on whether or not the
host parameter is specified or not.

The Application, local implementation and remote implementation all
have the same interface, so a possibility might be something like the
following:

To me forwarding each call in the Application class looks a little bit
redundant and I would like to get rid of it. Does anyone have any
comments or suggestions? Can metaclass programming come to rescue?

It sounds like you could probably get away with just a factory function:

def Application(program, host=None):
if host is None:
return LocalApplication(program)
else:
return RemoteApplication(program, host)

Then just implement the same interface and/or derive from a common base
class for LocalApplication and RemoteApplication.

HTH!,

-Marshall
 
B

Bruno Desthuilliers

Marco Nawijn a écrit :
Hello,

I have a hard time figuring out an elegant and efficient design for
the following problem.

I am working on automation of structural design problems. In the
majority of cases, this boils down to executing programs in batch in
one or more loops. The scripts to control the execution differ from
fortran to bash to python and so on. Most of them are ad hoc and what
I call 'throw away scripts'. In order to improve the situation I would
like to develop a Python module that supports the execution of
external programs. Ideally I would like to make running locally or
remote trivial for the users of the module. As an example, I would
like the following (pseudo)-code to work:

app = Application('patran') # Run on local
machine
app.start(args)


app = Application('patran', host='myhost') # Run on remote machine
app.start(args)

The problem I face is that the implementation of the application class
is completely
different for the local and remote case. The local case is a
straightforward implemenation using the subprocess module, the remote
case is a CORBA implementation. Somehow I would like to switch from
implementation class at runtime depending on whether or not the host
parameter is specified or not.

The solution is quite straightforward, and is known as the "factory"
design pattern.
The Application, local implementation and remote implementation all
have the same interface, so a possibility might be something like the
following:

class Interface(object):
.....
def start(self): pass
def stop(self): pass

What's the use of this class ? In Python, inheritance is for
implementation only.
class LocalImplementation(Interface):
.....

class GlobalImplementation(CorbaGlobalImplementation, Interface):
.....


class Application(Interface):

def __init__(self, program, host=None):
....
if host:
self.__impl = LocalImplementation(program)
else:
self.__impl = GlobalImplementation(program, host)

# Forward all methods to the implementation class
def start(self):
self.__impl.start()

def stop(self):
self.__impl.stop()

My my my... How to uselessly overcomplexify things...

class LocalApp(object):
def __init__(self, program):
# code here
def start(self):
# code here
def stop(self):
# code here

class RemoteApp(object):
def __init__(self, program, host):
# code here
def start(self):
# code here
def stop(self):
# code here

def Application(program, host=None):
if host is None:
return LocalApp(program)
else:
return RemoteApp(program, host)


To me forwarding each call in the Application class looks a little bit
redundant

Indeed !-)
and I would like to get rid of it.

cf above. But in case you need to do proper delegation in Python, the
magic words are "__getattr__" and "__setattr__". Here's a very basic
example of using __getattr__ - using __setattr__ is a bit more tricky,
but you'll find all relevant documentation in the FineManual(tm):

class Wrapper(object):
def __init__(self, obj):
self.__obj = obj

def __getattr__(self, name):
return getattr(self.__obj, name)
Does anyone have any
comments or suggestions? Can metaclass programming come to rescue?

May I suggest that you first learn Python bases before going into
complex things ?

And FWIW, googling for "KISS" might help too !-)

HTH
 
M

Marco Nawijn

It sounds like you could probably get away with just a factory function:

def Application(program, host=None):
if host is None:
return LocalApplication(program)
else:
return RemoteApplication(program, host)

Then just implement the same interface and/or derive from a common base
class for LocalApplication and RemoteApplication.

HTH!,

-Marshall

Thanks! This makes perfect sense. (In these moments I always wonder
why I didn't come up
with this idea...)

Thanks again.

Regards,

Marco
 
L

Lawrence D'Oliveiro

The problem I face is that the implementation of the application class
is completely different for the local and remote case. The local case is a
straightforward implemenation using the subprocess module, the remote
case is a CORBA implementation.

Any reason why you need to use something as complex as CORBA? On *nix
systems, depending on filesystem access issues, the difference between
local and remote execution of commands isn't much more than

cmd

versus

ssh host cmd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top