Nuss… E Agora?!?

10jul/080

“Talvez normalizar não seja normal”

Hoje vai mais um lembrete que propriamente um artigo: a idéia dele me foi mandada pelo Mário. Ele me mandou esse artigo em inglês lá do Coding Horror que mostra problemas causados pela extrema normalização em Banco de Dados.

Prestem bastante atenção quando o Jeff Atwood diz que "você deve normalizar quando os dados te disserem para fazê-lo" e não simplesmente por ser mais elegante ou teoricamente correto. Isso não significa que seu código deva ser anárquico, completamente contrário às regras de boa programação, e sim que ele seja adequado ao que escopo que o projeto prevê.

Para quem quiser mais informação sobre essa lógica, coloquei aqui no Nuss... e Agora?!? há algum tempo o artigo Padrões de Projeto: questão de bom senso. Ele fala exatamente sobre essa briga entre os pontos de vista de "faça por ser útil" e "faça por ser elegante" focado na análise de sistemas.

Lembrem-se: "Adequação, não perfeição"

22abr/087

Padrões de Projeto: questão de bom senso

Tá, eu já falei várias vezes sobre as maravilhas de se usar padrões de projeto, como eles resolvem problemas e coisas do gênero. Porém, fica sempre uma dúvida no ar: quando usar Padrões de Projeto?

29mar/080

Post mortem de um projeto que não nasceu

Aí eu vejo pessoas na Unidev que ridicularizam os novatos com o já clássico "vou fazer um MMORPG". Ta, é realmente absurdo ver um cara falar "sou iniciante" e "quero fazer um MMOG" na mesma sentença. É como entrar na faculdade de engenharia e querer montar no quintal de casa a torre mais alta do mundo.Agora, sejamos francos: os caras são iniciantes e, graças aos programistas de revistinha de banca, o mercado foi banalizado: qualquer um acha que é muito fácil fazer qualquer coisa. Então, ao invés de metralhar (mais) os sujeitos falando "isso não vai ser terminado", pq não dizer pra eles "por quê não vão terminar"?

É pra isso que eu vou começar essa lista e esperar que vocês a debatam, enfeitem, critiquem e aumentem. Eu vou editando assim que novas coisas forem surgindo e espero que tenhamos uma lista bem grande de motivos com os quais se preocupar. Ah, é claro, é também pra ter uma lista para linkar toda vez que alguém vier com mais um "eu sou iniciante mas vou fazer um MMORPG".

15nov/070

Mais problemas… E agora?!?

Nesse exato momento, estamos tentando resolver um problema meio chatinho. Até então, estávamos desenvolvendo o Jogo SEM a camada de Armazenamento, já que isso simplifica (e muito) o nosso trabalho. Para acessar as cartas do BD, usávamos métodos com lógica falsa que simulava um acesso ao Armazenamento, mas que, na realidade, construíam tudo o que era pra ser construído diretamente em código.

Eu vi um leitor ali com cara de “oO?”. Xô passar um exemplo: A gente tem um método BuscarCartas() que deveria ir à camada de Armazenamento e materializar todas as cartas para que a interface pudesse desenhá-las. DEVERIA, mas não está fazendo isso. Pelo contrário: BuscarCartas() está cheia de linhas de código que criam diretamente aquele monte de cartas que deveriam ter sido buscadas no Armazenamento.

“Ta Tiago, mas qualé o problema disso?”. O problema é que o exemplo cresceu demais. Antes isso funcionava perfeitamente, pois ainda estávamos acertando o funcionamento básico da interface e as interações dela com a lógica do caso de uso Batalhar. Agora que precisamos trabalhar corretamente com a diversidade de cartas entre os jogadores, o troço não dá vazão: temos que ficar criando métodos falsos um em cima do outro, o que tem me deixado com medo. No final, se esse monte de métodos continuar crescendo, pode dificultar muuuuito a inserção da camada de Armazenamento.

Ainda não está nada certo, mas o Douglas deu a idéia de utilizar um padrão chamado Database Broker (ou só DB Broker), uma Indireção entre a camada de Armazenamento e o resto do programa. Assim, uma vez criado o DBBroker, todos os acessos ao armazenamento vão ser realizados por ele, bem como funciona com a Controladora. Independente de como seja implementado o Armazenamento, basta trocar a lógica dos métodos do DBBroker que tudo está 100% funcional.

“E por que fazer isso?” Pois nosso BD vai ser inicialmente uma tabelona XML mesmo. Estamos tendo trabalho suficiente com a interface e a interação dela com a lógica para implementarmos um BD distribuído. Somos só 3, nada de inchar o design ;)

P.S.: Caso algum de vocês leitores já passaram por algum problema do gênero, agradeceria muito se rolasse uma ajuda com esse problema!

P.S.2: Desculpem pela falta de matérias, mas realmente não tô tendo muito sobre o que postar: graças à esse rolo, não muito tem acontecido no Jogo. Pelo menos, a solução vai virar um outro artigo.

P.S.3: Não não, realmente prefiro o Wii. - Já vi isso em algum outro lugar ;)

20out/072

MVC e o Linkage: O que se deve ou não fazer? (parte 2)

Agora que todos já sabem como funciona o MVC, vou continuar com a 2a e última parte do artigo. Hoje vou mostrar os pontos positivos e negativos da implantação da arquitetura, além de finalmente mostrar o que isso tudo tem a ver com o Linkage.

Pontos positivos:

  • Abstração e desacoplamento das camadas

Quando estamos programando a interface do problema, não nos preocupamos com a programação da lógica dele, somente com o que vai e o que vem dela. Dessa forma, podemos facilmente simular todo o funcionamento da lógica do programa com uma classe de testes que simula o funcionamento da lógica. Esse é o conceito de caixa preta, importantíssimo para o bom funcionamento de um software.

  • Facilidade de manutenção

Graças a esse desacoplamento, é muito mais fácil realizar a manutenção de um programa desses. Se for um problema visual, você vai à camada responsável pelo visual do programa e pronto, corrige. Se for um problema de lógica, é na lógica que você buscará a solução. Além disso, graças ao padrão Controlador (Controller), você pode apagar toda uma janela sem perder nada de sua implementação.

Quem está acostumado a adicionar código em um botão sabe exatamente o trabalho que isso ta poupando, mas para quem não está, aí vai um exemplo. Sabe esse Mario 2 que refizeram em 3D pro Nintendo DS? Se eles não usaram o MVC para fazer o original, perderam uma gigantesca parte da lógica do programa só por trocar a interface. Em compensação, usando o MVC de forma correta eles trocariam toda a interface sem mexer em 1 linha da lógica.

  • Possibilidade de Expansão

A estrutura de camadas proposta no MVC pode (e deve) ser expandida: criar mais camadas aumenta a coesão e diminui o acoplamento, organizando melhor o seu código. No jogo, por exemplo, além da Lógica e da Interface, temos a camada de Comunicação (rede) e a camada de Armazenamento (Banco de Dados), além das camadas entre elas. Um outro jogo pode, por exemplo, ter uma camada de IA, uma camada de hardware e uma camada de comunicação com outro jogo. O nosso, inicialmente, está assim:

piramide

As camadas se comunicam através de Indireções, como os já citados padrões Controlador, Proxy e DBBroker. Isso claro, pode mudar durante a análise de Casos de Uso mais avançados, mas inicialmente, essa é a idéia. Além disso, o funcionamento desses padrões vai ficar para futuros artigos.

  • Facilidade de realização de testes

Com o programa modularizado, podemos criar classes de teste que rodam nosso programa à exaustão, podendo encontrar bugs estatisticamente impossíveis de encontrarmos. Mas sabe qual é o melhor? Você pode testar isso tudo sem ter NADA de interface pronta: a lógica fica tão independente que chega a funcionar sem a interface. Então não precisamos esperar que o pessoal do desenvolvimento resolva aquele problema dos relatórios para que o pessoal do teste disseque nosso Caso de Uso. Maneiro, não?

Pontos negativos:

  • Programação complexa

A programação torna-se mais complexa quando aplicamos o MVC. Chamadas consecutivas e abstração do código são extremamente importantes. Além disso, uma documentação de todo o projeto é imprescindível para que as camadas sejam mapeadas e seguidas da forma correta. Além disso, teremos o...

  • Uso extensivo de padrões de projeto

O MVC simples já dita o uso do padrão Controller. Expandindo camadas de Comunicação e Armazenamento, ainda usaremos Proxies como o Remote Proxy e Database Brokers. Para desacoplar essas camadas, criaremos várias classes baseadas nos padrões Indireção (usado para desacoplar 2 classes que não deveriam ter visibilidade entre si) e Invenção Pura (padrão que adiciona classes que não estão diretamente ligadas ao problema em si, mas que facilitam a solução dele). No final, a relação entre as classes é bem mais burocrática

  • Dependência do MVC na portabilidade

Para poder portar um código MVC de forma correta, o programa que irá recebê-lo precisa trabalhar nos moldes do MVC. Por exemplo, se estamos portando uma janela de cadastro de cliente já pronta para um programa parecido, ele tem que estar modularizado de forma a trabalhar com a classe Controladora para que a manutenção seja mínima. Isso causa uma certa dependência à estrutura.

  • Queda de performance

As mensagens trocadas navegam entre camadas de forma burocrática e indireta, o que faz com que os programadores “performance acima de tudo” reclamem bastante. Por exemplo, uma chamada a uma função que seria direta numa programação estruturada torna-se uma cadeia de várias subchamadas a métodos que somente levam a chamada para a próxima camada nessa estrutura, como vocÊs viram no diagrama de seqüência lá em cima.

A performance perdida está longe de ser relevante, principalmente com os processadores de hoje em dia, mas mesmo assim continua sendo um ponto negativo da arquitetura.

“Ta, ta, eu entendi o MVC. Mas o quê que o Linkage tem à ver com isso???” O linkage do Flash é uma facilidade ao trabalhar com a interface, pois permite que uma classe use os atributos do MovieClip como se fossem atributos de si mesma. A grosso modo, parece muito uma herança de atributos e métodos públicos. O maior problema é que, se não tomarmos cuidado, acabamos destruindo toda a modularidade do MVC.

O linkage só deve ser usado para que as classes de interface controlem os MovieClips relacionados à elas. No nosso jogo, temos as classes TCarta e TCartaAvatar, ambas controlando uma carta em jogo. A diferença é que, seguindo o MVC, modularizamos uma carta em 2 camadas:

  • TCarta

Controla a lógica da carta: os atributos, as contas, o dano que ela recebe, se ela está no Deck, na Mão, em Jogo ou no Cemitério e coisas do gênero.

  • TCartaAvatar

Controla todos os efeitos visuais da carta. É ela que desenha a marcação do mouse sobre a carta, quem coloca a carta em qualquer posição, que inicia/pára o arrastar, que gera os efeitos de dano e desenha na tela todos os atributos buscados de TCarta.

Dessa forma, podemos trocar completamente a interface sem mexer nas classes de lógica. Trocar para Papervision 3D, a Plasticvision 4D, a Metalvision 5D ou até mesmo OpenGL ou ClosedLG, no nosso projeto, é muuuito mais simples: basta que criemos as mesmas classes de Interface, mas agora programadas com a nova interface. MOLEZA.

Essa portabilidade ainda pode ser da interface para a lógica: nossas cartas são arrastadas independente da lógica, elas brilham independente dlógica, elas se movem independente da lógica. Basta chamar os métodos da classe de Interface na hora certa, seja em Action Script 3.0 ou qualquer outra linguagem que o Flash suporte mais pra frente.

Caso uma única classe fosse responsável por isso tudo, durante uma troca de interface ou na hora de portar um trecho do código, a manutenção seria muito mais complicada: você deveria ficar movendo/apagando métodos das classes de lógica. Isso claro, pois estou pensando numa classe bem feita, com métodos bem estruturados. Muitas vezes, o que você encontra são linhas de interface no meio da lógica. Aposto que vários de vocês já viram um “se (this.morto) rode (“AnimacaoMorto”)”. Imaginem trocar o código para o futuro suporte OpenGL nesse caso...

Se vocês já pegaram o esquema do MVC e da expansão que fizemos, criando a camada de Armazenamento, já sacou que a carta também terá uma camada de armazenamento. Ela não está implementada ainda, mas seria mais ou menos assim:

  • TCartaDados

Seria a classe responsável por materializar e desmaterializar a Carta. Pra quem não sabe, materializar é buscar os dados de um objeto no BD e criá-lo em memória e desmaterializar é jogar no BD, destruindo o objeto da memória. Essa classe também seria responsável por todos os outros métodos possíveis

Gente, de todos os artigos que fiz até agora, esse foi de longe o que eu mais gostei de escrever. Espero, por meio desse, ajudar a derrubar essa história de que o Action Script é uma linguagem de 2a linha e que jogo em Flash é um amontoado de gambiarras. Espero também incentivar os leitores a escrever sobre qualidade de software em AS. Dá mais trabalho na hora de programar, mas esse trabalho é recompensado na hora de reutilizar o código em diversos outros projetos. Pensem nisso e até a próxima!

[EDIT] Não se esqueça de conferir o resto do artigo! Parte 1 e Parte 3, valeu?

17out/070

MVC e o Linkage: O que se deve ou não fazer? (parte 1)

Eu acredito que muita gente vai me chamar de maluco depois desse artigo, mas espero que todos entendam. Pra começar, vamos falar do MVC (ou Model-View-Controller), uma arquitetura de software baseado na idéia de interações emtre camadas de alta coesão (fazem exatamente aquilo que se propõem a fazer e nada mais que isso) e baixo acoplamento (são o mais independentes possível entre si).

“CALMAÊ!!!! QUE NEGÓCIO É ESSE DE ARQUITETURA??? O MVC NÃO É UM PADRÃO DE PROJETO???” Pois então, como eu disse, muita gente vai me chamar de maluco... Deixa eu explicar:Eu já vi vários sites, artigos e livros chamando o MVC de várias coisas. Já vi chamando de padrão de projeto, com o que eu não concordo. Ele não é um padrão de projeto pelo fato de organizar todo um sistema, não somente um bloco ou pequeno problema. Além disso, para implementar o MVC nós precisamos utilizar padrões, como o controlador (Controller).

Pensando nisso, algumas pessoas começaram a chamá-lo de meta-padrão, coisa que ele não é. Um meta-padrão definiria o comportamento dos padrões, não de toda a arquitetura.

O MVC é isso: ele define como as classes vão se comportar, ditando quem fica onde, faz o quê e, o mais importante, o por quê disso ser assim, bem como faz uma planta de uma casa. Por isso é que, em vários locais (como aqui no Nuss), vocês vão encontrar o MVC como uma arquitetura de software.

Isso é um ponto de vista, não chega a influenciar diretamente no uso do MVC. Mas é importante explicar para que ninguém saia com “cara de LG”. Beleza? Então continuemos com o artigo.

Voltando às camadas, é como se você transformasse o software no corpo humano: separasse os ossos e delegasse a eles a sustentação do corpo, o sangue ficaria com o transporte de substâncias pelo organismo e o sistema neurológico se responsabilizasse pela propagação das sensações e ordens do cérebro. É claro que as funções não são bem essas, mas é assim que as coisas funcionam.

O MVC em nosso jogo fica assim:

camadas

Com esse diagrama eu posso falar da maior característica do MVC: Toda e qualquer camada só se comunica com as camadas imediatamente abaixo de si. Lembrando-se que, para evitar dúvidas, quanto mais próxima do usuário, mais “alta” ou “alto nível” está a camada. Nota-se que nenhuma classe da Lógica realiza chamadas à classe Controladora da mesma forma que a classe controladora não realiza chamadas à Interface. Além disso, a Interface não chama diretamente método algum da Lógica: isso é feito através da classe Controladora, como mostra o Diagrama de Seqüência a seguir:

sequencia

No MVC, cada camada tem uma função específica:

  • Model (Modelo / Lógica)

Essa é a camada de negócios, onde está toda a lógica do teu sistema. No Jogo, por exemplo, é onde estão as classes TCarta, TPersonagem, TLadrilho e todas as outras relacionadas ao funcionamento do núcleo do Jogo (ou engine, se preferir).

  • View (Visão / Interface)

Na camada de visão você não encontra NADA além das classes de interface com o usuário. TCartaAvatar, TPersonagemAvatar e TLadrilhoAvatar são exemplos de classes que, no Jogo, ficam na Interface. Outras classes que estão aqui são a TIdioma (que controla todos os textos do programa) e a TJukeBox (recém implementada, que controla todos os sons do jogo)

  • Controller (Controladora)

A controladora é uma camada intermediaria entre a Lógica e a Interface, que faz somente a propagação das mensagens da interface para a lógica, visto que a lógica não pode se comunicar com a interface.

A continuação do artigo, com os prós e contras da arquitetura, além do que o Linkage do flash tem a ver com isso vai ficar para o próximo. Então gente, até lá!

[EDIT] Seguem os links para as Partes 2 e 3 do artigo.

24set/071

Singleton: Limitando e Distribuindo

O nosso Jogo tem uma característica muito especial: ele é traduzido dinamicamente, sem a necessidade de recompilação. Para isso, estamos colocando todo o texto em uma classe especial, a TIdioma. O problema é que, se nós estivéssemos utilizando um objeto simples, a cada “new” que déssemos, teríamos uma cópia inútil do objeto ocupando espaço inutilmente. Dessa forma, se tivéssemos 500k de texto, poderíamos estar ocupando vários megas da memória.

Isso, quando temos um projeto pequeno, não faz tanta diferença: acaba-se sabendo tudo que está ou não na memória, principalmente quando somente um programador fez aquilo tudo. Porém, há uma grande falha de programação: quando agregássemos um novo programador, ele teria que saber TUDO que já foi feito, da forma que foi feita, entendendo a lógica de tudo que já tá pronto para, aí sim, programar sem erros.Para resolver esse problema, o primeiro padrão de projeto que usamos para resolver um problema no Jogo foi o Singleton. Esse padrão GoF garante que a classe possui somente uma instância, criando um ponto de acesso global à ela. Isso é feito da seguinte forma: o programador NÃO cria um objeto daquela classe. Ao invés disso, a própria classe testa se ela possui uma instância dela mesma. Em caso negativo, a classe cria e retorna essa instância para o programador; em caso positivo, ela simplesmente retorna essa instância já criada.

Utilizamos esse tal de Singleton para garantir que, durante toda a execução do nosso programa, tivéssemos somente uma ÚNICA classe de tradução jogada na memória. Ela é criada no início do programa e, então, todo acesso à TIdioma é realizado via um ponteiro para ela.

O singleton pode ser aplicado à qualquer classe que você queira limitar. Abaixo vai o código genérico que deve ser aplicado:

package
{
	public class TSingleton
	{
		// Atributo de instância
		private static var _instancia:TSingleton = new TSingleton();

Esse atributo _instancia é a chave toda do Singleton e será explicado mais abaixo. O interessante é ver que, com o = new TSingleton(); a instância é inicializada na hora da criação do objeto.

		 // Atributo de teste
		private var _valor:int;

_valor é um atributo qualquer. Vamos usar aqui só para testar o funcionamento do padrão Singleton.

O construtor de uma classe Singleton deveria, por definição, ser protegido, para que, ao tentar usá-lo, o compilador desse um erro. Porém, o Action Script 3.0 NÃO PERMITE construtores privados. Como resolver isso?

		 //-----------------------------------------------------------
		public function TSingleton()
		{
			if (_instancia)
				throw new Error("Uso: TSingleton.Instancia.Metodo()");
		}

Quando _instancia é iniciada lá em cima, na criação da classe, o construtor é chamado a 1ª e única vez. Todas as outras vezes que alguém tentar construir na mão a classe, o teste é vai garantir que não seja possível criar uma segunda instância.

“Mas Tiago, se eu num posso chamar o construtor, como que eu vou criar um objeto da TSingleton???”. Isso é fácil. Você NÃO CRIA!Mas hein?!?

		//-----------------------------------------------------------
		// Esse método é o que iremos chamar daqui pra frente
		 // ao invés do construtor da classe
		public static function get Instancia():TSingleton
		{
			return TSingleton._instancia;
		}

Toda vez que você precisar acessar um método de uma classe com o Singleton (no nosso caso, a própria TSingleton), você vai usar pela linha TSingleton.Instancia.Metodo() (onde Metodo() é qualquer método da classe), garantindo que em TODAS AS VEZES você está acessando a mesma instância. Abaixo, mais 2 outros métodos de teste.

		//-----------------------------------------------------------
		// Método simples para retornar um atributo qualquer,
		// nesse caso, ‘valor’
		public function Valor():int
		{
			return this._valor;
		}

		//-----------------------------------------------------------
		// Como o método anterior, mas agora setando o valor do
		// atributo
		public function SetarValor( valor:int )
		{
			 this._valor = valor;
		 }
		//-----------------------------------------------------------
	}
}

Agora vai uma classe extra mostrando como usar uma classe com o padrão Singleton. A lógica de uso, nesse caso específico, está imbutida no construtor da classe, mas poderia estar em qualquer local.

Explicando passo a passo:

import TSingleton;

TODA classe que terá visibilidade de Singleton DEVE incluí-la. Dessa forma, mesmo sendo uma classe Global, áreas do programa que NÃO deveriam vê-la, NÃO verão. Isso evita muitos problemas de acoplamento, efeitos colaterais e melhora muito a reutilização.

public function TPrincipal()

{

	// Provocando o erro:

	//var teste:TSingleton = new TSingleton();

	TSingleton.Instancia.SetarValor(345);

	this.Exibe();

}

Como o construtor da TSingleton está protegido do acesso do programador, usar var teste:TSingleton = new TSingleton() vai resultar no erro:

Error: Uso: TSingleton.Instancia.Metodo()

at TSingleton$iinit()

at TPrincipal$iinit()

Lembrando que Uso: TSingleton.Instancia.Metodo() é a string que passamos para throw new Error lá no construtor de TSingleton, permitindo que vocês troquem a mensagem para algo mais descritivo, caso queiram.

Só para terminar, eu ressalto que esse é somente um dos vários algoritmos diferentes para o Singleton que vocês podem encontrar aí pela internet. Ele foi criado pelo Douglas prá nossa TIdioma há algumas poucas semanas, pois nenhum dos que encontramos era satisfatório o suficiente. Alguém aí tem mais algum exemplo do Singleton?


PS.: Aqueles que querem mesmo testar o Singleton, os arquivos estão aqui ó. Download Action Script 3.0 Singleton class (portuguese) here. Saiba mais: Wikipedia

16set/077

Padrões de Projeto: O que são e pra que servem?

Quando começamos o projeto em Action Script 2.0, começamos a ter problemas com o Flash, já que não tínhamos prática para montar um projeto mais robusto. Foi quando o Douglas (naquela época o Mário não estava ainda com a gente) começou a recorrer aos grandes fórums sobre o assunto, para resolver problemas de boa programação. Depois das 4 primeiras respostas, o meu mundo mudou completamente.

Foi impossível não notar uma característica chave em todos os locais onde procuramos informações: os “grandes usuários” desses locais não sabiam absolutamente NADA de POO (Programação Orientada a Objetos) e SEMPRE criticavam nosso código, dando para a gente uma solução POG (Programação Orientada à Gambiarras).

“Tiago, você está falando a maior besteria da tua vida” vocês podem dizer, mas antes de qualquer coisa, o exemplo clássico do que eu estou falando foi quando estávamos com o clássico problema de escopo do AS2.0, onde o “this” dentro de um método sobrecarregado apontava para a classe de onde ele veio, ao invés de apontar para a classe que o sobrecarregava. Antes de encontrarmos o Ellipsis (um pacotão de atualizações) e a classe Delegate, nos foi dada a seguinte resposta por um dos “grandes usuários”: “Teu código está muito burocrático. Pega todos os métodos, bota num script na 1ª frame que ele vai funcionar”. Lindo, não???

É CLARO que eu não vou falar onde nem quem mandou fazermos tamanha bizonhice, mas não posso deixar de comentar a baixa qualidade geral dos códigos que vejo por aí. Variáveis Globais pra tudo q é lado, programação monolítica (um arquivo único de 15mil linhas) e, principalmente, ignorância absoluta sobre a existência dos Padrões de Projeto, o básico do básico em qualquer aplicação com qualidade e profissionalismo.

O conceito de Padrões de Projeto (Design Patterns, em inglês, também chamados de padrões de projeto de software ou padrões de desenho de software) vem da década de 70, mas foram realmente implementados catalogados mesmo lá pro final da década de 80, por Kent Beck e Ward Cunningham. Os Padrões são conjuntos de soluções para determinados problemas no desenvolvimento do seu software. Essas soluções já foram tão testadas por aí que foram padronizadas, recebendo um nome, o problema que ele resolve, a forma com que ele resolve e as conseqüências do seu uso. A idéia era que, quando falássemos do padrão X, soubéssemos exatamente sobre o que falamos.

Um padrão de projeto possui sempre um Diagrama de Classes (como esses aqui) relacionado a ele, usado para mostrar para os programadores como o código deve ficar. Uma vez conhecido o padrão e entendido como programá-lo, fica muito fácil resolver problemas graves ou que geram muita programação inútil.

Há uma reserva quanto ao uso de Padrões de Projeto: mesmo aumentando a reutilização das soluções enquanto você ainda está projetando o software, eles diminuem consideravelmente a reutilização de blocos pequenos de software, já que você vai ter que gastar um tempinho extra na manutenção das classes. Nada que a gente já não faça, mas o uso indiscriminado pode fazer com que seu projeto fique muito pouco reaproveitável.

Apesar disso, o verdadeiro maior problema que encontramos para adicionar os padrões ao nosso projeto foi que a Orientação a Objetos do AS2.0 era falha: existia, mas o foco ainda era a estruturação. Talvez por isso as pessoas fizessem gambiarras híbridas sem a menor pena. Em compensação, quando migramos para o AS3.0 e nos deparamos com OO pura, vimos que ele está completamente preparado para a confecção de softwares de nível profissional.

Então, daqui pra frente, quando disserem pra vocês que o Action Script 3.0 é uma linguagem de programação inferior, podem bater de frente. Eu mesmo vou colocar aqui algumas matérias sobre padrões de projeto aqui. Já estou preparando algumas sobre os padrões State, Concrete Factory e Singleton (em parceiria com os verdadeiros programadores do meu projeto, claro) e, se mais algum leitor programar em AS3.0 e quiser fazer o mesmo, me mande o link que vou colocá-lo aqui.

13set/071

Os problemas de se focar na perfumaria.

Estava olhando projetos postados por aí quando notei um erro recorrente na maioria dos projetos: as pessoas começam pela perfumaria.

A perfumaria era um termo usado por meu professor de Multimídia e Interfaces Homem-Máquna, Projeto Final e tantas outras que designava as coisas bonitinhas que não têm influência direta no andamento do projeto. Coisas como o ícone do programa, as janelas, os mapas... tudo isso se encaixa no termo perfumaria.O termo perfumaria também pode ser traduzido como a interface do programa. Então, começar pela perfumaria é como começar um jogo pensando nas cores e formas das magias, ao invés de se preocupar com a programação delas.

3set/073

Atraso em projetos de horas vagas (Ou “Olha… já tamo devendo quase 3 semanas…”)

Lembram-se que eu fiquei de falar sobre os problemas com os quais nós iríamos nos deparar? Pois então, depois do Design Inchado e da Escolha do Flash, não acredito ter esquecido desse pequeno problema...

Que pequeno problema, Tiago?” você pergunta. Sabe quando a gente passa o dia todo trabalhando numa coisa séria, que exige atenção completa e dedicação total? Aí, depois que a gente chega em casa, cansado, o quê que vamos fazer? “Tomar aquele banho”, “jogar Crysis”, “cair na cama e dormir”, todas essas são respostas válidas. Agora, me responde uma coisa: e se você ainda tivesse um jogo pra fazer? Pois então, aí que ta o problema. Todo aquele tempo de descanso, aquela hora de reflexão pra saber quem é o assassino da Taís, aquelas horinhas para escrever no Nuss... E Agora?!?, isso tudo vai pro saco.

Fazer um trabalho fora do trabalho é EXTREMAMENTE DIFÍCIL pelo simples fato de que você não pode mais jogar Warcraft III o domingo todo, não pode sair pra organizar o churrasco de aniversário, nem ir ao rodízio de pizza sem que isso afete o tempo que você tem para terminá-lo. E, apesar disso tudo ser muito lógico e extremamente idiota de ser lido, EU NUNCA FUI AVISADO DISSO!!!!!!!

Só depois de uma conversa com o Douglas que eu me toquei que o maior atraso do Jogo vem justamente dos contratempos que apertam nossas horas livres. É o meu trabalho extra que atrasa, é ele que fica preso a um PC ruim. E o Mário, coitado, ta há 2 semanas esperando que a gente quebre uma classe em 3 outras para aumentar a coesão e diminuir o acoplamento. Sim, estamos 2 semanas atrasados e, se bobear, caímos na 3ª.

Seria tudo mais fácil se nós 3 estivéssemos ganhando com o projeto, pegando 8h diárias para trabalhar única e exclusivamente nele. Daria tempo pr’eu pesquisar muitos jogos, pro Douglas dissecar o Action Script 3.0 e o Mário ler muito sobre padrões. Daria para fazermos nossas reuniões e gerenciarmos nosso projeto de uma forma profissional. Porém, já que não é assim (e eu sei que também não é assim prá vários de vocês), como minimizar esses problemas todos?

Pois então... No momento eu não consigo pensar em muitas coisas. Não tenho propriedade para escrever sobre como evitar atrasos nos projetos de horas-vagas (também conhecidos como “to fazendo um jogo” ou “ainda é só hobby”). Porém, o pouco de lógica e consciência que me restam (é quase 1h da manhã e tô quase dormindo no teclado...) me permite dar os seguintes toques:

1. Faça o que gosta
Quando estamos cansados, fazer o que gostamos torna o serviço leve, muuuuito mais aceitável. Se o serviço em si não lhe agrada muito e tem que ser feito...

2. Faça do jeito que você gosta
Procure resolver o problema de uma forma de que lhe agrade. Lembro do final do projeto final, quando passei uma semana trabalhando coisa de 6h diárias na documentação do dito cujo. Para tornar o serviço menos tedioso (acreditem), eu fiz todos os diagramas no Word.

“VOCÊ TÁ MALUCO, NÉ?!?” Olha, certa hora eu achei que sim. Mas eu trabalho tão bem com o Word que, acredito eu, maluco estaria se estivesse tentando fazer aquilo tudo em um outro programa, como o Rational Rose. Já que éramos obrigados a fazer a papelada toda, fiz duma forma que me era agradável. Um serviço cansativo pode acabar tornando-se um descanso. Para isso...

3. Faça com prazer
Isso significa que você deve fazer aquilo sem o peso da obrigação. Não estou dizendo para que você não leve seu projeto a sério, é só pra que você não encare a tarefa como se o seu salário dependesse daquilo. Se a mente não consegue funcionar mais, saia e descanse. Dê-se esse direito e as coisas vão ficar mais fáceis de aturar. Lembre-se: se não é seu emprego, então é um HOBBY.

4. Não se esqueça das outras atividades
Isso tem muito a ver com o tópico anterior. Não se tranque, não se feche, não se desespere. Lembre-se que, quando você não precisa cumprir horários, o chopp da 6ª feira não se torna um pecado. Realmente não dá pra ficar sem trabalhar? Então...

5. Concilie as coisas
Desenhamos muitos Diagramas de Classe e Seqüência em reuniões regadas à chopp numa praça de alimentação de um shopping em Friburgo. Isso tornou o trabalho muito mais simples de se aturar.

6. Organize-se!
Se você não se organiza, não tem tempo pra nada. Termine as coisas pendentes ao invés de arrumar mais coisas pra terminar. Tente montar uma rotina flexível, separando um tempo para teu projeto. Fazer um cronograma é sempre essencial, mensurando o que se consegue fazer e o tempo que se demora a fazê-lo. Se não há um limite para resolução daquele problema, não há noção de atraso. Se não há noção de atraso, também não tem como saber se o projeto vai sair e quando se espera que ele saia. Daí pra frente, tudo fica tão nebuloso que se acaba duvidando da viabilidade da tarefa.

7. Foque-se!
Sem foco, não há trabalho que renda. Se você vai tirar 1h do seu tempo livre, TIRE 1H DO SEU TEMPO LIVRE. Não faça mais nada que divida sua atenção. Gosta de ar livre? Então vá para a varanda, leve o lap top e aproveite o sol. Gosta de silêncio? Então tranque-se e trabalhe à vontade. Gosta de ouvir músicas? Então ouça aquilo que quiser, o quanto quiser.

Mas lembre-se: você está buscando o foco. Você saberá que alguma coisa deu errada quando deixar de trabalhar para cantar. Não liguem, acontece muito comigo quando o Winamp escolhe uma dos Chili Peppers.

Essas são coisas que, instintivamente, eu tenho feito para despiorar essa situação, mas podem não ser aplicáveis a todos os casos. De qualquer jeito, já é um ponto de partida por onde vocês poderão desenvolver suas próprias técnicas. Aliás, falando nisso, mais alguém aí tem alguma dica para passar?