Skip to content

Instantly share code, notes, and snippets.

@alexandre
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save alexandre/5bed42f22a639559fe14 to your computer and use it in GitHub Desktop.

Select an option

Save alexandre/5bed42f22a639559fe14 to your computer and use it in GitHub Desktop.
misturando strategy e herança.
"""
Vamos supor que temos um numero X de clientes e cada cliente tem 2 tipos de
fechamento diferentes: fechamento parcial e fechamento geral.
Além disso, cada cliente tem um padrão para esses arquivos (cada fechamento gera um), já que esses
arquivos serão utilizados em um sistema de terceiros.
A principio, eu pensei que apenas o pattern strategy solucionava o problema...
de acordo com o cliente eu devolvia uma classe especifica que geraria o
arquivo. Mas o problema é que eu esqueci que haviam 2 tipos de fechamento.
Com isso, eu pensei em utilizar herança. Por que? porque o processo básico
para chamar os arquivos de fechamento (indiferente do tipo) é o mesmo.
No final ficaria algo como:
>>> import exporters
>>> customer = Customer()
>>> exporters.ExporterA(customer=customer.name)
>>> exporter.generate_file()
>>> # o mesmo para o segundo tipo
>>> exporters.ExporterB(customer=customer.name)
>>> exporter.generate_file()
Obs.: Supondo que o meu entendimento do pattern strategy está correto. =]
"""
import collections
class Exporter():
@property
def default_exporter(self):
raise NotImplementedError('Should have implemented this')
@property
def available_exporters(self):
raise NotImplementedError('Should have implemented this')
def __new__(cls, *args, **kwargs):
if 'customer' not in kwargs.keys():
raise RuntimeError('You have to inform a customer name')
exporter_type = super(Exporter, cls).__new__(cls)
exporter = collections.defaultdict(
lambda: exporter_type.default_exporter, exporter_type.available_exporters)
return exporter[kwargs['customer']](*args, **kwargs)
class ExporterA(Exporter):
@property
def default_exporter(self):
return default_exporter_a
@property
def available_exporters(self):
return {
'Customer_foo': exporter_a_customer_foo,
'Customer_bar': exporter_a_customer_bar,
'Customer_ble': exporter_a_customer_ble,
}
class ExporterB(Exporter):
@property
def default_exporter(self):
return default_exporter_b
@property
def available_exporters(self):
return {
'Customer_foo': exporter_b_customer_foo,
'Customer_bar': exporter_b_customer_bar,
'Customer_ble': exporter_b_customer_ble,
}
@alexandre

Copy link
Copy Markdown
Author

@drgarcia1986 e @daniloakamine-luizalabs

Apenas um rascunho mental enquanto eu não paro para ler...

# module exporters.py
import collections

EXPORTERS_A = collections.defaultdict(
     lambda: default_a_exporter,
     {
         'Customer_foo': exporter_a_customer_foo,
         'Customer_bar': exporter_a_customer_bar,
         'Customer_ble': exporter_a_customer_ble,
     }
)

EXPORTERS_B = collections.defaultdict(
     lambda: default_b_exporter,
     {
         'Customer_foo': exporter_b_customer_foo,
         'Customer_bar': exporter_b_customer_bar,
         'Customer_ble': exporter_b_customer_ble,
     }
)

class Closer:
    def __init__(self, exporter):
        self.exporter = exporter

    def generate_file(self, *args, **kwargs):
         return self.exporter.generate_file(*args, **kwargs)
customer = Customer()

# mesmo processo para o EXPORTERS_A e o EXPORTERS_B

exporter = exporters.EXPORTER_A[customer.name]()
closer = exporters.Closer(exporter)
closer.generate_file('xyz') # ... segue a vida

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment