<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DestaqueBlog &#187; boas práticas</title>
	<atom:link href="http://weblog.destaquenet.com/tag/boas-praticas/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Django e settings.py: dicas e boas práticas</title>
		<link>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/</link>
		<comments>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 01:32:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=415</guid>
		<description><![CDATA[Em vez de ficar rasgando elogios ao Django, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo settings.py, cuja função &#8230; <a href="http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Em vez de ficar rasgando elogios ao <a href="http://djangoproject.com">Django</a>, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo <code>settings.py</code>, cuja função é fornecer as configurações necessárias para que o projeto funcione. Apesar deste módulo ser uma peça importante em qualquer projeto Django, pouco se fala sobre ele, ou sobre boas práticas associadas a ele. Por isso, achei que seria interessante mostrar a minha visão pessoal sobre o assunto.</p>
<h3>O poder do Python</h3>
<p>Quem não está acostumado a trabalhar com Django pode estranhar o fato deste utilizar um script <a href="http://python.org">Python</a> para fazer a configuração do projeto: o famoso <code>settings.py</code>. E essa estranheza é justificada, afinal muitos desenvolvedores &#8212; principalmente os que vêm de outras linguagens &#8212; estão acostumados a trabalhar com ferramentas onde tal tarefa é feita com arquivos XML ou coisa assim.</p>
<p>O fato é que utilizar um script Python para tal é uma excelente idéia, pois você deixa de depender de algum tipo de estrutura estática (e muitas vezes inconveniente) para algo mais flexível e poderoso, que, no caso, é a própria linguagem de programação. Isso faz uma grande diferença em situações onde tal flexibilidade é necessária.</p>
<p>Quer exemplos?<span id="more-415"></span></p>
<h3>Ambientes de desenvolvimento/produção</h3>
<p>Eis como fizemos aqui. Primeiramente, defina a variável de ambiente <code>WORKSPACE</code>. No Linux, isso pode ser feito através do arquivo <code>~/.bashrc</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">WORKSPACE</span>=<span style="color: #000000;">1</span></pre></div></div>

<p>A idéia é possibilitar a criação de perfis de configuração, cada qual correspondente a um ambiente de execução. A existência ou não da variável de ambiente é o que define o ambiente no qual a aplicação roda.</p>
<p>Continuando com o exemplo, no diretório raíz do seu projeto Django, crie o módulo <code>environment.py</code>, com o seguinte conteúdo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff7700;font-weight:bold;">not</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'WORKSPACE'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span></pre></div></div>

<p>Finalmente, modifique o módulo <code>settings.py</code> para que este utilize tais métodos onde for necessário definir configurações diferentes para ambientes de execução diferentes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações padrão</span>
PREPEND_WWW = <span style="color: #008000;">False</span>
DEBUG = <span style="color: #008000;">True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações para ambiente de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    PREPEND_WWW = <span style="color: #008000;">True</span>
    DEBUG = <span style="color: #008000;">False</span>
&nbsp;
MIDDLEWARE_CLASSES = <span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">'django.middleware.common.CommonMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.sessions.middleware.SessionMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.auth.middleware.AuthenticationMiddleware'</span>,
    <span style="color: #483d8b;">'django.middleware.doc.XViewMiddleware'</span>,
    <span style="color: #483d8b;">'pages.middleware.PageFallbackMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.redirects.middleware.RedirectFallbackMiddleware'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Habilitando caching em modo de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    MIDDLEWARE_CLASSES += <span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">'django.middleware.cache.UpdateCacheMiddleware'</span>,
        <span style="color: #483d8b;">'django.middleware.cache.FetchFromCacheMiddleware'</span>,
    <span style="color: black;">&#41;</span></pre></div></div>

<p>Não tenha medo de utilizar os recursos do Python onde eles se fizerem necessários, apenas tomando cuidado para não exagerar e acabar criando acidentalmente um <a href="http://en.wikipedia.org/wiki/Genetic_algorithm">Algoritmo Genético</a> para configurar seu projeto!</p>
<h3>Informações secretas (IPs, usernames, passwords, etc)</h3>
<p>Praticamente não há quem ignore a importância de um bom sistema de controle de revisões (<a href="http://subversion.tigris.org">Subversion</a>, <a href="http://git-scm.org">Git</a>, etc). O problema é que, muitas vezes, não tomamos o devido cuidado com o que colocamos dentro dos nossos repositórios. Sempre que possível, informações secretas &#8212; como endereços de IP, usernames e passwords &#8212; devem ser mantidas fora dos repositórios.</p>
<p>Em um projeto Django, as informações de acesso a servidores de e-mail e bancos de dados devem estar disponíveis através do módulo  <code>settings.py</code>. Felizmente, existe um jeito simples de manter essas informações separadas das outras configurações.</p>
<p>Primeiramente, abra o arquivo <code>settings.py</code> do seu projeto e remova todas as senhas e outras informações que você considere secretas. Em seguida, cole o seguinte trecho de código no final do arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> private <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>Feito isso, crie o módulo <code>private.py</code> no diretório raíz do seu projeto Django. Coloque nele as configurações que você removeu do <code>settings.py</code> no passo anterior. Exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
SECRET_KEY = <span style="color: #483d8b;">'secret_key_do_seu_projeto'</span>
&nbsp;
EMAIL_HOST = <span style="color: #483d8b;">'localhost'</span>
EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_local'</span>
&nbsp;
DATABASE_HOST = <span style="color: #483d8b;">'localhost'</span>
DATABASE_USER = <span style="color: #483d8b;">'username_db_local'</span>
DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_local'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    EMAIL_HOST = <span style="color: #483d8b;">'ip_email_producao'</span>
    EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_producao'</span>
&nbsp;
    DATABASE_HOST = <span style="color: #483d8b;">'ip_db_producao'</span>
    DATABSE_USER = <span style="color: #483d8b;">'username_db_producao'</span>
    DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_producao'</span></pre></div></div>

<p>Certifique-se de adicionar o arquivo <code>private.py</code> no <em>ignore</em> (<code>.cvsignore</code> para <a href="http://www.nongnu.org/cvs/">CVS</a>, <code>.gitignore</code> para Git, etc) correspondente ao sistema de controle de revisões sendo utilizado. Faça o commit e pronto.</p>
<p>Para finalizar, se o seu repositório já contém uma versão &#8220;insegura&#8221; do módulo <code>settings.py</code>, mude as senhas dos seus servidores.</p>
<h3>E você, o que recomenda?</h3>
<p>Tem alguma dica útil para compartilhar conosco? Nós adoraríamos ouvir o que você tem a dizer!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Por favor, usem typesafe enums!</title>
		<link>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/</link>
		<comments>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 02:20:35 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[análise]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[enums]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[modelagem]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=349</guid>
		<description><![CDATA[Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama UML Entidade-Relacionamento a seguir: Nem irei perder tempo explicando esse &#8230; <a href="http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama <span style="text-decoration: line-through;">UML</span> Entidade-Relacionamento a seguir:</p>
<div id="attachment_358" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01.png"><img class="size-medium wp-image-358" title="Diagrama" src="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01-300x218.png" alt="Modelo-exemplo de banco de dados" width="300" height="218" /></a><p class="wp-caption-text">Modelo-exemplo de banco de dados</p></div>
<p>Nem irei perder tempo explicando esse modelo, até porque não há nada nele que precise de explicações. Bem, na verdade, há uma coisa sim: <strong>por que raios existe uma tabela só para armazenar os tipos de contato?!</strong> Qual é o problema com os bons e velhos códigos fixos (1-email, 2-celular, N-&#8230;)?</p>
<p>Um argumento a favor dessa abordagem é que &#8220;o usuário pode querer cadastrar um contato cujo tipo não seja suportado pela aplicação&#8221;. Mas será mesmo que colocar essa informação no banco de dados resolve o problema? E, mais importante, existe algum efeito colateral?</p>
<p>Bem, na minha experiência, embora essa abordagem pareça boa o bastante para resolver a questão num sistema simples de &#8220;cadastro&#8221;, a bomba explode quando o sistema passa a depender dessas flags para a realização de lógicas de negócio que vão além do famigerado CRUD. <span id="more-349"></span></p>
<h3>Anti-pattern?</h3>
<p>E se eu te dissesse que usar tabelas no banco de dados para armazenar flags é um anti-pattern? Digo isso pois, como veremos a seguir, as vantagens são irrisórias frente às desvantagens:</p>
<p><strong>Poluição do modelo de dados.</strong> Um sistema não muito grande provavelmente conta com mais de uma centena de tabelas. Isso todo mundo sabe. O que todo mundo também sabe, mas parece ignorar, é que não seria surpreendente constatar que 10-15% dessas tabelas serviriam apenas para armazenar flags (situação de pedido, estado civil, forma de pagamento, e por aí vai). E o pior: essas tabelas, quase sempre, possuem exatamente a mesma estrutura, que apelidei carinhosamente de <strong>tabelas código-descrição</strong>. A tabela <code>TipoContato</code>, mostrada no diagrama que encabeça este texto, é um exemplo desse tipo de tabela.</p>
<p><strong>Ruim para o meio ambiente.</strong> Poluir o modelo de dados com dezenas de <strong>tabelas código-descrição</strong> torna o modelo desnecessariamente maior e mais difícil de compreender. Imprimir um modelo desses consome mais papel, o que é ruim numa época onde o desenvolvimento sustentável está em voga. Quantas árvores suas <strong>tabelas código-descrição</strong> já derrubaram?</p>
<p><strong>Ultra-normalização.</strong> Quanto mais tabelas uma consulta envolver, mais joins, e mais dados indo e vindo para o banco de dados. E, considerando que o banco de dados é (quase) sempre o gargalo, isso não é muito bom para a performance do seu sistema.</p>
<p><strong>Poluição do modelo de objetos.</strong> As linguagens com suporte à orientação a objetos figuram entre as <a href="http://www.tiobe.com/content/paperinfo/tpci/index.html">mais usadas atualmente</a>, por isso eu diria que muito provavelmente você utiliza esse paradigma no desenvolvimento dos seus sistemas. Se este for o caso, também é bem provável que você utilize algum framework ORM para facilitar a tarefa de integração do software com o banco de dados. Como muitos frameworks ORM exigem um modelo de objetos compatível com o modelo de dados, bem, você acaba sendo forçado a poluir seu modelo de objetos com classes burras que apelidei carinhosamente de (pasmem!) <strong>classes código-descrição</strong>.</p>
<p><strong>Se tem tabela, tem cadastro.</strong> Bom, já que todas as flags possuem suas tabelinhas no banco de dados, isso significa que você, pobre desenvolvedor, terá que fazer &#8220;cadastros&#8221; para todas elas (e reze para não precisar fazer relatórios, também). Além da chatisse costumeira de se fazer um cadastro, devemos levar em consideração que fazê-los consome tempo e, tempo é dinheiro.</p>
<p><strong>Código quebradiço.</strong> Essa é feia. Vamos supor que, nessa nossa aplicação de gerenciamento de clientes/contatos, você queira incluir uma funcionalidade que permita enviar um torpedo ao cliente caso ele possua um contato do tipo <code>Celular</code>. Como mostrado no trecho de código a seguir, você fatalmente terá que incluir no código-fonte referências a registros armazenados no banco de dados, tornando o código quebradiço. Consequentemente, um único <code>UPDATE</code> ou <code>DELETE</code> executado por engano no banco de dados pode fazer o sistema cair de joelhos.</p>
<p>Enviando torpedos a um cliente:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Tenta localizar um contato do tipo celular</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// WTF!! Estamos referenciando um registro do banco de dados!!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getCodigo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> 10L<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>A solução</h3>
<p>Com certeza existem outros problemas que eu acabei deixando passar, mas espero que os problemas que listei já sejam o suficiente para te convencer que guardar flags em tabelas no banco de dados é uma má idéia.</p>
<p>Mas, como resolver isso então? Simples: <strong>use enums sempre que possível.</strong> A única desvantagem é que os usuários não poderão mais sair criando novas flags a torto e a direito, o que não é realmente um problema frente às vantagens que as enums oferecem<strong>.<br />
</strong></p>
<p><strong>Poluição do modelo de dados?</strong> As flags virariam campos numéricos ou alfanuméricos nas tabelas que as usam e o framework ORM se encarregaria de converter esses campos de/para objetos enum. Diga adeus às <strong>tabelas código-descrição</strong>.</p>
<p><strong>Ruim para o meio-ambiente?</strong> Sem as <strong>tabelas código-descrição</strong>, seu modelo fica menor, mais enxuto, facilitando a visualização e gastando menos papel ao imprimí-lo. A natureza agradece.</p>
<p><strong>Ultra-normalização?</strong> Usando enums você diminui a quantidade de ligações entre as tabelas, tornando as entidades um pouco mais auto-contidas. Menos tabelas, menos joins, mais performance.</p>
<p><strong>Poluição do modelo de objetos?</strong> As enums tomariam o lugar das <strong>classes código-descrição</strong>, o que por si só tornaria o código mais claro, pois, ao contrário das classes &#8220;normais&#8221;, as enums possuem um propósito bem definido.</p>
<p><strong>Se tem tabela, tem cadastro?</strong> Ué, por que você está com esse sorriso estampado no rosto?</p>
<p><strong>Código quebradiço?</strong> Quem mais se beneficia das enums são os trechos de código onde as lógicas de negócio são definidas. Mais especificamente, seu código deixa de referenciar registros do banco de dados, eliminando a fragilidade e melhorando a legibilidade. As enums também impedem que valores arbitrários sejam usados em atribuições e comparações, tornando o código ainda mais confiável. Um exemplo disso pode ser visto no código a seguir, que é uma adaptação <span style="text-decoration: line-through;">da atrocidade</span> do código mostrado anteriormente:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// Bem melhor agora!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getTipo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> TipoContato.<span style="color: #006633;">CELULAR</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O fato de a sua linguagem do coração não ter suporte nativo a enums não deve ser um impedimento para que você deixe de usufruir de suas vantagens. <a href="http://www.ditchnet.org/wp/2005/05/08/typesafe-enum-pattern-in-python/">Existem formas</a> de se conseguir uma funcionalidade semelhante sem muito esforço.</p>
<h3>Conclusão</h3>
<p>Desenvolver software é, antes de tudo, fazer escolhas. É o custo/benefício, os prós e contras antes de se tomar uma decisão. A boa notícia é que o nosso produto, o software, é maleável o suficiente para permitir que decisões ruins sejam re-feitas sempre que elas resultam em problemas como o descrito neste texto.</p>
<p>Bom carnaval!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

