Por Paula Grangeiro • PythonRio Junho 2018
#WebDeveloper #Senior #Python #Freelancer #Pyladies
#DesignPatterns #QualidadeCódigo
As linguagens de programação evoluíram de acordo com a interação homem x código.
Estruturado
Procedural
Orientado à Objeto
Funcional
...
- Acoplamento
+ Coesão
Código procedural em estrutura de classes
"(...) most of us (developers) use those languages (OO) without knowing why, and without knowing how to get the the most benefit out of them." - Robert C. Martin
Single Responsability Principle
Open/Closed Principle
Liskov Substituition Principle
Interface Segregation Principle
Dependency Inversion Principle
Uma classe deve ter um (e apenas um) único motivo para ser modificada
class Impressora:
def __init__(self, cartuchos, folhas):
self.cartuchos = cartuchos
self.folhas = folhas
def valida_cartucho(self):
# verifica se cartucho tem tinta
def valida_folha(self):
# verifica se existem folhas
def imprime(self, informacao):
valida_cartucho()
valida_folhas()
for folha in folhas:
# pruuu pri pripri pri
# imprimindo informacoes
class Cartucho:
def __init__(self, **kwargs):
# inicializa cartucho
def validate(self):
# valida estado do objeto cartucho
class Folha:
def __init__(self, **kwargs):
# inicializa objeto folha
def validate(self):
# valida estado do objeto folha
class Impressora:
def __init__(self, cartuchos, folhas):
# inicializa impressoa
def imprime(self, informacao):
# valida cartuchos e folhas e imprime
for folha in folhas:
# pruuu pri pripri pri
# imprimindo informacoes
Você deve ser capaz de extender o comportamento de uma classe, sem modificá-lo.
class Impressora:
def __init__(self, cartuchos, folhas):
# inicializa impressoa
def imprime(self, informacao):
# valida cartuchos e folhas e imprime
for folha in folhas:
# pruuu pri pripri pri
# imprimindo informacoes
class BaseImpressora:
def imprime(self, informacao):
self.impressor.imprime(informacao)
class ImpressoraFolha(BaseImpressora):
def __init__(self, cartuchos, folhas):
self.impressor = ImpressorFolhas(cartucho, folhas)
class Impressora3D(BaseImpressora):
def __init__(self, filamento):
self.impressor = Impressor3D(filamento)
class ImpressorFolhas:
def __init__(self, cartuchos, folhas):
# inicializa
def imprime(self, informacao):
for folha in folhas:
try:
# imprime informacao
# cabô espaço da folha
# lança exceção
except NaoTemMaisEspacoFolhaError:
continue
except NaoTemMaisTintaCartuchoError:
raise CaboTintaError()
class Impressor3D:
def __init__(self, filamento):
# inicializa
def imprime(self, informacao):
while filamento.exist():
filamento.imprime(informacao)
Classes derivadas devem ser facilmente substituídas por suas superclasses.
class BaseImpressora:
def imprime(self, informacao):
self.impressor.imprime(informacao)
class ImpressoraFolha(BaseImpressora):
def __init__(self, cartuchos, folhas):
self.impressor = ImpressorFolhas(cartucho, folhas)
class Impressora3D(BaseImpressora):
def __init__(self, filamento):
self.impressor = Impressor3D(filamento)
class ImpressaoController:
def __call__(self, informacao, cartuchos=None, folhas=None, filamento=None):
if folhas:
impressora = ImpressoraFolha(cartuchos, folhas)
else:
impressora = Impressora3D(filamento)
impressora.imprime(informacao)
class Impressora:
def __init__(self, impressor):
self.impressor = impressor
def imprime(self, informacao):
self.impressor.imprime(informacao)
class BaseImpressor:
def imprime(self, informacao):
raise NotImplementedError
class ImpressorFolhas(BaseImpressor):
def __init__(self, cartuchos, folhas):
# inicializa impressor
def imprime(self, informacao):
for folha in folhas:
try:
# imprime informacao
# cabô espaço da folha
# lança exceção
except NaoTemMaisEspacoFolhaError:
continue
except NaoTemMaisTintaCartuchoError:
raise CaboTintaError()
class Impressor3D(BaseImpressor):
# implementa impressor 3d
class ImpressorXablau(BaseImpressor)
# implementar impressor xablau
class ImpressaoController:
def __call__(self, impressora, impressor, informacao):
impressora = Impressora(impressor)
impressora.imprime(informacao)
Interfaces devem ser refinadas e específicas por cliente
class Impressora:
def __init__(self, impressor):
self.impressor = impressor
def imprime(self, informacao):
self.impressor.imprime(informacao)
class ScanMixin:
def scan(self, informacao):
# implementa scan
class Impressora:
def __init__(self, impressor):
self.impressor = impressor
def imprime(self, informacao):
self.impressor.imprime(informacao)
class Multifuncional(ScanMixin, Impressora):
pass
Dependa de abstrações, não de concretos.
class ImpressoraFolha(BaseImpressora):
def __init__(self, cartuchos, folhas):
self.impressor = ImpressorFolhas(cartucho, folhas)
class ImpressorFolhas:
def __init__(self, cartuchos, folhas):
# inicializa
def imprime(self, informacao):
for folha in folhas:
try:
# imprime informacao
# cabô espaço da folha
# lança exceção
except NaoTemMaisEspacoFolhaError:
continue
except NaoTemMaisTintaCartuchoError:
raise CaboTintaError()
class Impressora:
def __init__(self, impressor):
self.impressor = impressor
def imprime(self, informacao):
self.impressor.imprime(informacao)
class BaseImpressor:
def imprime(self, informacao):
raise NotImplementedError
contato@paulagrangeiro.com.br
paulagrangeiro.com.br
@pgrangeiro