|
|
# Introdução à Engenharia de Software
|
|
|
|
|
|
Programar não é muito difícil. Fazer seu programinha, seu projetinho, fazendo sozinho e depois você deixa lá guardado em geral não dá problema.
|
|
|
|
|
|
O único software que acaba é o que foi jogado no lixo. Todo software muda e precisa mudar, seja porque o ambiente mudou, a linguagem mudou, o chefe pediu um novo relatório, a empresa sofreu uma fusão ou a legislação que regulamenta a atividade mudou. Na vida real não é uma questão de SE o software vai mudar, é uma questão de QUANDO.
|
|
|
|
|
|
E esse software é difícil de fazer. Principalmente com várias pessoas, é uma coleção de grandes e pequenas coisas que fazem a diferença na qualidade do software e na produtividade da equipe.
|
|
|
|
|
|
Hoje a maior parte das linguagens para esses sistemas usa programação orientada a objetos, uma tecnologia muito legal. Mas quando estudar ela você vai ver que ela aumenta muito a quantidade de maneiras diferentes que uma coisa pode ser feita, projetada, programada. E isso é ruim do ponto de vista de uma equipe de desenvolvimento. Alguém pode ter que mexer no seu código e ele precisa entender rápido como as coisas estão organizadas. Então é muito normal a criação de padrões nas equipes ou comunidades. Padrões de organização e gerenciamento de equipes, de codificação, e até respostas prontas de como modelar algumas relações de organização e interação de dados que aparecem repetidamente, esses são os "design patterns".
|
|
|
|
|
|
Até coisas bem relacionadas a codificação como nome de funcao_com_underscore ou funcaoEmCamelcase fazem diferença na prática da programação. Alguns padrões de codificação são apoiados por linguagens como a [PEP8](https://www.python.org/dev/peps/pep-0008/) pra python e o uso de camelcase em java e alguns até viram parte da linguagem como XXX onde funções que são públicas tem que ter nome começando com letra maiuscula.
|
|
|
|
|
|
O objetivo desse texto é explicar um pouco sobre MVC
|
|
|
|
|
|
|
|
|
## Disclaimer
|
|
|
|
|
|
|
|
|
Para alguns exemplos vou usar um sistema/aplicativo financeiro.
|
|
|
|
|
|
Vou falar bastante de java pq em geral é de onde esses padrões vem e é onde eles fazem mais sentido.
|
|
|
|
|
|
É um pouco complicado falar de MVC e Django, mas ainda vale a pena entender a organização do MVC pro projeto.
|
|
|
|
|
|
O MVC é dividido em Model-View-Controller, mas dentro do Django a view do MVC é em geral chamada de "template" e o controller do MVC é que é chamado de "view". Vai ficar mais claro com exemplos, agora vamos falar só de MVC primeiro.
|
|
|
|
|
|
|
|
|
Por enquanto esqueça tudo que você sabe e leu sobre como o Django funciona, vamos falar de MVC.
|
|
|
|
|
|
|
|
|
# MVC
|
|
|
|
|
|
É um dos padrões de projeto mais usados, a algum tempo atrás todo framework procurava ser organizado conforme o MVC, nem sempre dava 100%, mas MVC ainda é o contexto geral.
|
|
|
Ele é dividido em três partes: Model, View e Controller. Que funcionam como três blocos para organizar o código, pense nisso como se eles dividissem responsabilidades.
|
|
|
|
|
|
**View** é a camada de visualização, tudo referente a formatação dos dados. Por exemplo, se os dados precisam chegar ao usuário como json eles devem chegar para a view como um array/vetor e na view é que vai ser convertido para json.
|
|
|
|
|
|
**Controller** faz a comunicação entre view, model e o ambiente. Por exemplo: é ele que recebe um formulário do cliente, ai pede pra model validar, processar
|
|
|
|
|
|
**Model** é a parte maior do sistema, é o que faria a parte pesada de calculos nos sistemas. Não é bem o nosso caso pq nossos calculos são feitos pelo pandas e guardados em uma forma da cache, mas . No mundo java costuma ser dividido em várias camadas pra lidar com diferentes tarefas. Por exemplo, em java:
|
|
|
|
|
|
- uma camada de abstração de dados (DAO). O modo como os SGBDs retêm os dados e o modo como as linguagens ou frameworks retêm os dados e as ligações entre eles é bastante diferente, então é preciso ficam convertendo de um modo para o outro. Para evitar um inferno no código criamos uma série de funções para essas conversões e chamamos de camada DAO (data access object). Essa camada também cuida das conexões ao banco de dados. Em geral existem bibliotecas para fazer esse trabalho como:
|
|
|
- [django query system](https://docs.djangoproject.com/en/1.11/topics/db/queries/) o que o django dá pra gente
|
|
|
- [SQLAlchemy](https://www.sqlalchemy.org/) é o framework mais geral pra isso em python
|
|
|
- [Hibernate](http://hibernate.org/) pra Java, é o mais famoso do ramo
|
|
|
- uma camada de lógica de negócio (BO). Por exemplo, colocar restrições a um cara pegar emprestimo ou não
|
|
|
- uma camada de validação dos dados de entrada.
|
|
|
|
|
|
A maior parte das operações vai passar por todas as camadas da model. Para realizar um emprestimo
|
|
|
|
|
|
|
|
|
```Python
|
|
|
class Model:
|
|
|
|
|
|
class DAO:
|
|
|
# funções de banco de dados e conexões
|
|
|
|
|
|
class BO:
|
|
|
def valida_emprestimo(formulario):
|
|
|
pessoa = model.dao.get_pessoa(formulario.pessoa) # via de regra, o dao só é usado dentro do BO
|
|
|
|
|
|
if pessoa.conta.saldo <= 0: # validação de regra de negócio
|
|
|
return 'negado'
|
|
|
|
|
|
return 'OK'
|
|
|
|
|
|
def processa_emprestimo(formulario):
|
|
|
status = valida_emprestimo(formulario) # sim, pode repetir a validação
|
|
|
# a menos que ela seja lenta demais
|
|
|
if status != 'OK'
|
|
|
return status
|
|
|
|
|
|
emprestimo = Emprestimo()
|
|
|
emprestimo.valor = formulario.valor
|
|
|
# ...
|
|
|
model.dao.salva_emprestimo(emprestimo)
|
|
|
|
|
|
return 'OK'
|
|
|
|
|
|
|
|
|
def controller_emprestimo(formulario):
|
|
|
|
|
|
if not model.valida_dados(formulario):
|
|
|
return Error()
|
|
|
|
|
|
status = model.bo.processa_emprestimo(formulario)
|
|
|
|
|
|
if status == 'OK':
|
|
|
view.mostra_sucesso()
|
|
|
else:
|
|
|
view.mostra_fracasso()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
A ideia é que partes da model sejam reutilizáveis. No exemplo, um sistema bancário online e um aplicativo android desse banco para simular empréstimos (os dois usando java):
|
|
|
|
|
|
- a view é completamente diferente pq as tecnologias de visualização são diferentes (HTML x template XML do android)
|
|
|
- o controller também, pq o aplicativo não vai fazer todas as operações do sistema financeiro e o ambiente web é diferente de um aplicativo. Na web as coisas chegam como requisições HTTP já no aplicativo são outras formas de comunicação com o ambiente as coisas podem ficar em memória e não vem como requisições fechadas.
|
|
|
- *Model*:
|
|
|
- A validação pode mudar, em um sistema web existem mais maneiras de tentar burlar o sistema
|
|
|
- O DAO deve mudar, com o banco de dados diferente
|
|
|
- A camada de BO pode ser reutilizada, nem tudo vai ser usado, mas a função `model.bo.valida_emprestimo` e outras pra calcular a forma de parcelamento (e juros decorrentes disso, etc) podem ser reaproveitadas. Não é só uma questão de reaproveitamento, é também pela sincronia, se o código é compartilhado, quando as regras no servidor mudarem o aplicativo também vai mudar pra sincronizar e manter tudo consistente. -- depois da nova versão liberada e o usuário atualizar, mas ainda assim. -- Melhor do que ter códigos diferentes que talvez tenham resultados inconsistentes e gerem confusão pro cliente e pesadelos pra quem desenvolve.
|
|
|
|
|
|
|
|
|
Revisão:
|
|
|
MVC serve para:
|
|
|
1. organizar o código em áreas de responsabilidade.
|
|
|
2. facilitar o reaproveitamento de código da área de regras de negócio. O resto costuma depender da tecnologia do ambiente então não tem muito o que fazer.
|
|
|
|
|
|
|
|
|
# MVC no Django
|
|
|
|
|
|
Apesar do Django ter uma clara influência do MVC eles realmente conseguiram fazer as coisas piores. Mudaram a nomenclatura do model-view-controller, a tabela abaixo mostra a correspondência de nomes entre o MVC e a organização do Django.
|
|
|
|
|
|
|
|
|
| MVC | Django |
|
|
|
|------------|----------|
|
|
|
| model | model |
|
|
|
| view | template |
|
|
|
| controller | view |
|
|
|
|
|
|
|
|
|
|
|
|
## Use template tags
|
|
|
|
|
|
Sistemas de template como o do Django existem em praticamente todos os frameworks pra web.
|
|
|
Existem vários motivos de otimização para eles existirem, mas isso não é importante agora.
|
|
|
Ele forçam separação entre o processamento dos dados e a apresentação deles, forçam uma organização do código. Mas isso também restringe o que podemos fazer lá, dentro de templates não se pode escrever código arbitrário, só se pode usar as funções dos templates, tags e filters. Mas tente manter a separação do MVC, passe arrays pro template, cuide deles lá.
|
|
|
|
|
|
É razoavelmente comum em algum ponto do projeto precisar [escrever o seu próprio](https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/) template_tag ou filter.
|
|
|
|
|
|
|
|
|
### template como segurança
|
|
|
|
|
|
Alguns caracteres como o `<`, `>` e `&` são especiais em HTML e quando se vai escrever o valor de uma variável no HTML é preciso garantir que essa variável não contém os caracteres especiais. Na realidade deve-se substituir esses caracteres pelas [entities html](https://www.w3schools.com/html/html_entities.asp) correspondentes
|
|
|
para garantir que a variável seja interpretada como texto e não como comandos HTML. Isso é necessário para prevenir ataques [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting).
|
|
|
|
|
|
Como um efeito disso, o código abaixo não vai dar o resultado que você quer:
|
|
|
|
|
|
```Python
|
|
|
# views.py
|
|
|
|
|
|
def view(request):
|
|
|
return render('my_template.html', {'title': '<title>Título</title>'})
|
|
|
|
|
|
# my_template.html
|
|
|
|
|
|
{{ title }}
|
|
|
|
|
|
``` |
|
|
\ No newline at end of file |