Back-End

27 mai, 2013

Entendendo o conceito de apps plugáveis

Publicidade

Para os desenvolvedores que já trabalharam com outras tecnologias como PHP, Java, Asp.NET ou até outros frameworks, o Django traz uma nova visão sobre um “sistema”. No Django, um sistema é formado por vários “apps plugáveis”, e mudar a forma de pensar/planejar/desenvolver para essa nova abordagem é um dos grandes desafios que encontramos no Django.

Na maioria dos sistemas/sites que desenvolvemos, temos uma ou várias funcionalidades que já foram desenvolvidas, e aqui entra o já conhecido conceito DRY do Django, porque se eu já fiz determinada funcionalidade, por que desenvolver novamente?

Vamos para um exemplo bem simples e muito usual, que é um app para comunicação entre o visitante/usuário do sistema/site e o proprietário. Hoje em dia, com as redes sociais, temos inúmeros meios de comunicação: Twitter, Facebook, Google+, Instagram, LinkedIn, Foursquare, Pinterest… Isso sem contar o velho e-mail! Imagina se toda vez que você for desenvolver um produto novo, seja sistema ou site, tenha que codificar novamente todas as interações com esses meios de contato? Complicado né?

Exemplo da abordagem de apps plugáveis:

Requisitos do sistema XPTO:

  1. Gerenciamento dos clientes;
  2. Comunicação do cliente via e-mail;
  3. Comunicação do cliente via redes sociais;
  4. Compartilhamento das informações do site nas redes sociais.

Com esses requisitos, a primeira ideia que temos é “já que é um sistema pequeno, vou fazer tudo em um app só e resolvo tudo ali dentro mesmo“. Essa ideia tem dois grandes erros: primeiro, não existe sistema pequeno. Vá por mim. E depois estamos usando um Framework e não estaríamos usando as boas práticas determinadas pelo Django.

Levando em conta os requisitos do sistema, iremos dividir nosso sistema em dois apps: primeiro, Cliente e segundo, Comunicação. Então vamos para o projeto, para tanto devemos abrir o terminal Linux/Mac ou cmd Windows (meu caso).

Criando o sistema demo_01

python c:\Python27\Scripts\django-admin.py startproject demo_01

O comando acima é bem simples. A parte de maior destaque é o demo_01, que é o nome do projeto/sistema que eu quero desenvolver. O resto é fixo do próprio Django. Agora vamos criar os dois apps: Cliente e Comunicação.

python manage.py startapp Cliente
python manage.py startapp Comunicacao

Precisamos agora criar em cada novo app um subdiretório static, onde deveremos colocar os arquivos estáticos (img, css, js) da referida app. Devemos criar a mesma estrutura para a app Comunicação.

|Cliente
|—__init__.py
|—models.py
|—views.py
|—tests.py
|—static
|——js
|——css
|——img

Agora o trabalho é feito de forma normal dentro dos models.py, views.py, etc, fazendo claro as divisões de quais classes devem pertencer ao app Cliente e quais ao Comunicação.

Como forma didática, irei criar as classes da app Comunicação, portanto não irei tratar dos acessos às APIs das redes sociais, nem irei levar em consideração questões de herança.

#-*- coding:utf8 -*-

from django.db import models

class Facebook(models.Model):
    login = models.CharField(max_length=100, unique=True, blank=False, null=False)
    email = models.EmailField(unique=True)
    senha = models.CharField(max_length=10)
    post = models.TextField(u'Conteúdo do novo post', blank=True, null=True)

    def publicar_post(self):
        u"""Método para publicar um novo post no Facebook"""
        pass

class Pintarest(models.Model):
    login = models.CharField(max_length=200, unique=True)
    senha = models.CharField(max_length=10)
    ...
    def pinar(self):
        u"""Metodo para criar um novo pin"""
        pass

class Twitter(models.Model):
    login = models.CharField(max_length=100)
    senha = models.CharField(max_length=30)
    twitter = models.CharField(max_length=140, blank=True, null=True)

    def twittar(self):
        u"""Método para tuitar"""
        pass

class Email(models.Model):
    emailRemetente = models.EmailField(u'Email remetente')
    nomeRemetente = models.CharField(u'Nome remetente', max_length=500)
    emailDestinatario = models.EmailField(u'Email destinatário')
    nomeDestinatario = models.CharField(u'Nome destinatário', max_length=500)
    emailBCC = models.EmailField(u'Email destinatário BCC', null=True, blank=True)
    nomeBCC = models.CharField(u'Nome destinatário BCC', null=True, blank=True, max_length=500)
    emailCC = models.EmailField(u'Email destinatário CC', null=True, blank=True)
    nomeCC = models.CharField(u'Nome destinatário CC', null=True, blank=True, max_length=500)
    tituloMensagem = models.CharField(u'Título da mensagem', max_length=300)
    tipoMensagem = models.BooleanField(u'Tipo da mensagem', default=False)
    prioridadeMensagem = models.IntegerField(u'Prioridade no envio da mensagem', default=0)
    confirmacaoEntrega = models.IntegerField(u'Confirmar envio da mensagem?', default=False)
    corpoMensagem = models.TextField(u'Corpo da mensagem')

    def enviar(self):
        destinatario = []
        try:
            destinatario.append(self.emailDestinatario)
            if self.emailBCC:
                destinatario.append(self.emailBCC)
            if self.emailCC:
                destinatario.append(self.emailCC)
            send_mail(self.tituloMensagem,
                      self.corpoMensagem,
                      self.emailRemetente,
                      destinatario,
                      fail_silently=True)
        except BadHeaderError:
            return 'Cabecalho invalido.'
        except Exception, e:
            pass

Agora nossa app de Comunicação já possui as classes necessárias para gerenciar os meios de contatos que desejamos fornecer no nosso sistema. Agora precisamos habilitar o admin desse app; para isso, vamos editar o arquivo admin.py – caso não exista, basta criá-lo, deixando-o conforme abaixo:

# -*- coding:utf-8 -*-

from Comunicacao.models import Facebook, Pintarest, Twitter, Email
from django.contrib import admin

admin.site.register(Facebook)
admin.site.register(Pintarest)
admin.site.register(Twitter)
admin.site.register(Email)

Agora temos a estrutura para que o admin do Django possa gerenciar as informações da app Comunicação.

Para não deixar o artigo muito longo, eu ocultei aqui a parte de criação das views e das urls, mas o que é necessário entender é que deste ponto em diante, em qualquer outro sistema/site que eu venha a precisar de funcionalidades de comunicação, basta copiar o diretório Comunicação, colar no novo sistema/site registrar no settings.py. Assim teremos todas as funcionalidades do app Comunicação sem refazer nenhuma linha de código. Se levarmos em consideração que temos no diretório static do app Comunicação, todos os arquivos js, css que desenvolvemos, nem a parte de AJAX para Comunicação será necessário refazer.

Agora, imaginem se a nossa abordagem fosse a de fazer tudo em um app apenas? #FAIL Portanto, tente separar o máximo possível as “funcionalidades” dos sistemas em apps, assim o DRY será muito utilizado, e vocês chegaram num ponto onde irão apenas “plugar” os apps já desenvolvidos anteriormente, quando forem desenvolver um novo sistema/site.

>>> print u’%s’ % (“Abraços”)