In questo scenario ho la funzione per il factory, la classe astratta e la classe che la implementa, il tutto in 3 file differenti.

Nella cartella “strategies” ho il file della classe abstract ed anche il file della classe che la implementa, la funzione in un file nella directory che contiene strategies.

L’obiettivo è avere una funzione, a cui viene passata una stringa di testo, che ritorni l’istanza della classe create con il factory pattern.

La funzione factory pattern con stringa di testo

Quando usiamo una funzione / classe importata da una libreria usiamo:

import libreria as lbr
lbr.faiQualcosa()

Siccome sia il nome del modulo della classe da istanziare é un testo, devo usare importlib ed eval.

Per l’importazione del modulo sma.py che si trova dentro la cartella strategies:

import importlib
i = importlib.import_module("strategies.sma")

Ovviamente poi la stringa di testo sarà dinamica.

Per lanciare una funzione da una stringa di testo facciamo

function_name = "strategy"
result = eval(function_name + "()")

Dove il nome del file SMA.py è lo stesso della classe. Quindi per ottenere una nuova istanza devo fare SMA(data).

Utilizzandole entrambe per questo caso specifico.

import importlib

def StrategyFactory(name, data):
    modu = 'strategies.' + name
    i = importlib.import_module(modu) 
    return eval("i." + name + "(data)")
Elegant Themes Prodotti

La classe abstract

from abc import ABC, abstractmethod

class Strategy(ABC):
    def __init__(self, data) -> None:
        self.data = data

    @abstractmethod
    def doSomething():
        pass

Nel constructor della classe abstract creo self.data che posso utilizzare poi in tutte le implementazioni.

La classe che implementa l’abstract

import strategies.strategy_abc as abc

class SMA(abc.Strategy):
    def doSomething(self):
        print(self.data)

In tutte le implementazioni devo implementare la funzione doSomethig.

0 commenti

Lascia un Commento

Vuoi partecipare alla discussione?
Sentitevi liberi di contribuire!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *