RoQuOTriX
RoQuOTriX

Reputation: 3001

Selecting executed method of class at runtime in python?

This question is very generic but I don't think it is opinion based. It is about software design and the example prototype is in python:

I am writing a program which goal it is to simulate some behaviour (doesn't matter). The data on which the simulation works is fixed, but the simulated behaviour I want to change at every startup time. The simulation behaviour can't be changed at runtime.

Example:
Simulation behaviour is defined like:

usedMethod = static

The program than looks something like this:

while(true)
    result = static(object) # static is the method specified in the behaviour
    # do something with result

The question is, how is the best way to deal with exchangeable defined functions? So another run of the simulation could look like this

while(true)
    result = dynamic(object)

if dynamic is specified as usedMethod. The first thing that came in my mind was an if-else block, where I ask, which is the used method and then execute this on. This solution would not be very good, because every time I add new behaviour I have to change the if-else block and the if-else block itself would maybe cost performance, which is important, too. The simulations should be fast.

So a solution I could think of was using a function pointer (output and input of all usedMethods should be well defined and so it should not be a problem). Then I initalize the function pointer at startup, where the used method is defined.

The problem I currently have, that the used method is not a function per-se, but is a method of a class, which depends heavily on the intern members of this class, so the code is more looking like this:

balance = BalancerClass()
while(true)
    result = balance.static(object)
    ...
    balance.doSomething(input)

So my question is, what is a good solution to deal with this problem?

I thought about inheriting from the balancerClass (this would then be an abstract class, I don't know if this conecpt exists in python) and add a derived class for every used method. Then I create the correct derived object which is specified in the simulation behaviour an run-time.

In my eyes, this is a good solution, because it encapsulates the methods from the base class itself. And every used method is managed by its own class, so it can add new internal behaviour if needed.

Furthermore the doSomething method shouldn't change, so therefore it is implemented the base class, but depends on the intern changed members of the derived class.

I don't know in general if this software design is good to solve my problem or if I am missing a very basic and easy concept.

If you have a another/better solution please tell me and it would be good, if you provide the advantages/disadvantages. Also could you tell me advantages/disadvantages of my solution, which I didn't think of?

Upvotes: 1

Views: 485

Answers (1)

rahul tyagi
rahul tyagi

Reputation: 643

Hey I can be wrong but what you are looking for boils down to either dependency injection or strategy design pattern both of which solve the problem of executing dynamic code at runtime via a common interface without worrying about the actual implementations. There are also much simpler ways just like u desrcibed creating an abstract class(Interface) and having all the classes implement this interface.

I am giving brief examples fo which here for your reference:

  1. Dependecy Injection(From wikipedia): In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object. A "dependency" is an object that can be used, for example as a service. Instead of a client specifying which service it will use, something tells the client what service to use. The "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it. The service is made part of the client's state.

Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

Python does not have such a conecpt inbuilt in the language itself but there are packages out there that implements this pattern.

Here is a nice article about this in python(All credits to the original author):

Dependency Injection in Python

  1. Strategy Pattern: This is an anti-pattern to inheritance and is an example of composition which basically means instead of inheriting from a base class we pass the required class's object to the constructor of classes we want to have the functionality in. For example: Suppose you want to have a common add() operation but it can be implemented in different ways(add two numbers or add two strings)

    Class XYZ():

    def __constructor__(adder):
    
        self.adder = adder
    

The only condition being all adders passed to the XYZ class should have a common Interface.

Here is a more detailed example: Strategy Pattern in Python

  1. Interfaces: Interfaces are the simplest, they define a set of common attributes and methods(with or without a default implementation). Any class then can implement an interface with its own functionality or some shared common functionality. In python Interfaces are implemented via abc package.

Upvotes: 2

Related Questions