<?xml version="1.0" encoding="utf-8"?>
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:bib="http://bibtexml.sf.net/" xmlns:q="http://cnx.rice.edu/qml/1.0" id="id84118" module-id="m12345" cnxml-version="0.6">
    <title>Introdução a Design de Software</title>
    <metadata xmlns:md="http://cnx.rice.edu/mdml/0.4">
  <!-- WARNING! The 'metadata' section is read only. Do not edit below.
       Changes to the metadata section in the source will not be saved. -->
  <md:content-id>m17494</md:content-id>
  <md:title>Introdução a Design de Software</md:title>
  <md:version>1.24</md:version>
  <md:created>2008/01/01 00:31:48 US/Central</md:created>
  <md:revised>2009/06/29 18:31:30.668 GMT-5</md:revised>
  <md:authorlist>
    <md:author id="guiga">
        <md:firstname>Guilherme Mauro</md:firstname>
        <md:surname>Germoglio Barbosa</md:surname>
        <md:fullname>Guilherme Mauro Germoglio Barbosa</md:fullname>
        <md:email>germoglio@gmail.com</md:email>
    </md:author>
  </md:authorlist>
  <md:maintainerlist>
    <md:maintainer id="guiga">
        <md:firstname>Guilherme Mauro</md:firstname>
        <md:surname>Germoglio Barbosa</md:surname>
        <md:fullname>Guilherme Mauro Germoglio Barbosa</md:fullname>
        <md:email>germoglio@gmail.com</md:email>
    </md:maintainer>
  </md:maintainerlist>
  <md:editorlist>
    <md:editor id="guiga">
        <md:firstname>Guilherme Mauro</md:firstname>
        <md:surname>Germoglio Barbosa</md:surname>
        <md:fullname>Guilherme Mauro Germoglio Barbosa</md:fullname>
        <md:email>germoglio@gmail.com</md:email>
    </md:editor>
  </md:editorlist>
  <md:license href="http://creativecommons.org/licenses/by/2.0/"/>
  <md:licensorlist>
    <md:licensor id="guiga">
        <md:firstname>Guilherme Mauro</md:firstname>
        <md:surname>Germoglio Barbosa</md:surname>
        <md:fullname>Guilherme Mauro Germoglio Barbosa</md:fullname>
        <md:email>germoglio@gmail.com</md:email>
    </md:licensor>
  </md:licensorlist>
  <md:keywordlist>
    <md:keyword>design de software</md:keyword>
    <md:keyword>engenharia de software</md:keyword>
    <md:keyword>princípios de design</md:keyword>
    <md:keyword>software</md:keyword>
  </md:keywordlist>
  <md:subjectlist>
    <md:subject>Science and Technology</md:subject>
  </md:subjectlist>
  <md:abstract>Este capítulo é uma introdução a design de software. Seu objetivo é fundamentar o conhecimento do estudante de forma a fazê-lo reconhecer a relevância e os benefícios proporcionados pelo design de software.</md:abstract>
  <md:language>pt-br</md:language>
  <!-- WARNING! The 'metadata' section is read only. Do not edit above.
       Changes to the metadata section in the source will not be saved. -->
</metadata>

<content>
        <para id="id84126">Antes de começarmos o estudo
            e a prática na disciplina de Arquitetura de
            Software, é apropriado sabermos onde ela se
            encaixa ao longo do Corpo de Conhecimento de
            Engenharia de Software (
            <emphasis effect="italics">Software Engineering
                Body of Knowledge</emphasis>). Design arquitetural,
            ou projeto da arquitetura, é a primeira das
            duas atividades que compõem a área de conhecimento
            de Design de Software (
            <emphasis effect="italics">Software Design
                Knowledge Area</emphasis>). A atividade
            seguinte é design detalhado. Por ser uma atividade
            de Design, o design arquitetural se faz por
            uma mistura de conhecimento e criatividade.
            Como criatividade é algo que se obtém através
            da experiência, não é nosso objetivo ensiná-la.
            No entanto, buscamos ao longo desse livro transmitir
            o conhecimento necessário para a criação de
            arquiteturas de sistemas de software.
        </para>
        <para id="id84155">Certamente, uma base conceitual
            em Design de Software é necessária para uma
            melhor compreensão desse livro. Dessa maneira,
            esse capítulo procura fundamentar o conhecimento
            do leitor nessa área, de forma que sua importância
            e seus benefícios proporcionados sejam reconhecidos.
            Em outras palavras, esse capítulo fará com
            que o leitor seja capaz de:</para>
        <list id="id84164" display="block" list-type="bulleted">
            <item id="uid1">Reconhecer os conceitos básicos
                de design de software </item>
            <item id="uid2">Descrever problemas de design
                através de seus elementos fundamentais
                </item>
            <item id="uid3">Identificar princípios de design
                de software e explicar seus benefícios
                </item>
            <item id="uid4">Diferenciar design de baixo-nível
                de design de alto-nível e saber quando
                aplicar cada um </item>
        </list>
        <section id="cid1">
            <title>Design de Software</title>
            <para id="id84227">A relevância de se projetar
                – ou fazer design de – software pode ser
                explicada pela complexidade crescente dos
                sistemas de software. Devido a essa complexidade,
                o risco de se construir um sistema que
                não alcance seus objetivos é eminente.</para>
            <para id="id84235">Para evitar tal risco, a
                prática comum de qualquer engenharia para
                se construir um artefato complexo, um sistema
                de software complexo em nosso caso, é construí-lo
                de acordo com um plano. Em outras palavras,
                <emphasis effect="italics">projetar</emphasis>
                o sistema antes de construí-lo. O resultado
                dessa atividade, também conhecida como
                de atividade de design, é também chamado
                de design. O design facilita em duas atividades
                que são essenciais no ciclo de vida de
                um sistema de software. Primeiro, ele possibilita
                a avaliação do sistema contra seus objetivos
                antes mesmo dele ser construído. Dessa
                maneira, ele aumenta a confiança de que
                o sistema construído alcançará seus objetivos.
                Obviamente, uma vez que nesse ponto há
                apenas o modelo do sistema – o design –,
                a avaliação não será completa, mas isso
                também não quer dizer que ela não ofereça
                resultados importantes para o sucesso do
                sistema. Já a outra atividade beneficiada
                pelo design é a própria construção do sistema,
                dado que ele também serve como guia para
                a implementação do software.
            </para>
            <para id="id84261">Para definir design de software,
                alguns autores o fazem em dois sentidos
                distintos: quando design de software é
                usado como 
                <emphasis effect="italics">produto</emphasis>
                e quando é usado como 
                <emphasis effect="italics">processo</emphasis>.
                Quando usado no primeiro sentido, o termo
                <emphasis effect="italics">design de software</emphasis>
                indica o produto que emerge do ato (ou
                processo) de projetar um sistema de software
                e sendo assim algum documento ou outro
                tipo de representação do desejo do projetista
                (ou designer). Esse produto é o resultado
                das decisões do designer para formar uma
                abstração do sistema que é desejado no
                mundo real. Já quando o termo é usado no
                segundo sentido, 
                <emphasis effect="italics">fazer design</emphasis>
                indica o processo seguido para se obter
                um projeto. Esse processo é orientado a
                objetivos, mas também orientado a pessoas.
                Ele envolve diversos interessados nos objetivos
                e extrai a essência do conhecimento do
                designer e do domínio do problema onde
                ele atua 
                <link target-id="bid0"/>.
            </para>
            <para id="id84304">A partir da visão de produto
                do design de software, podemos observar
                que ele deve descrever diversos aspectos
                de um sistema de software para que, assim,
                possibilite sua construção. Budgen menciona
                alguns desses aspectos 
                <link target-id="bid1"/>:
            </para>
            <list id="id84316" display="block" list-type="bulleted">
                <item id="uid5">a estrutura estática do
                    sistema, incluindo a hierarquia de
                    seus subprogramas; </item>
                <item id="uid6">os objetos de dados a serem
                    usados; </item>
                <item id="uid7">os algoritmos a serem usados;
                    </item>
                <item id="uid8">o empacotamento do sistema,
                    em termos de como os módulos estão
                    agrupados em unidades de compilação;
                    e </item>
                <item id="uid9">as interações entre módulos,
                    incluindo as regras de como elas devem
                    acontecer e sua motivação. </item>
            </list>
            <para id="id84382">Assim, podemos chegar a
                uma definição mais pragmática de design
                de software 
                <link target-id="bid2"/>:
            </para>
            <para id="id84392">
                <definition id="design-de-software">
                    <label>Definição</label>
                    <term>design de software</term>
                    <meaning id="design-de-software-significado">
                        É tanto o processo de definição
                        da arquitetura, módulos, interfaces
                        e outras características de um
                        sistema quanto o resultado desse
                        processo. </meaning>
                </definition>
            </para>
            <section id="uid10">
                <title>Características de Design de Software</title>
                <para id="id84408">Uma vez que projetar
                    os diversos aspectos de um sistema
                    de software é trabalhoso, mostraremos
                    a seguir os benefícios alcançados por
                    esse processo.</para>
                <para id="id84414">
                    <emphasis effect="italics">Design de
                        software permite avaliação prévia.</emphasis>
                    Como desenvolver software custa tempo
                    e dinheiro, não parece sensato alguém
                    investir seus recursos no desenvolvimento
                    de um sistema que não soluciona os
                    problemas propostos pelos interessados.
                    Dessa maneira, a avaliação prévia do
                    sistema se torna imprescindível para
                    garantir que ele alcance os objetivos
                    desses interessados. Como o design
                    descreve diversos aspectos que estarão
                    presentes no sistema quando construído,
                    ele permite esse tipo de avaliação.
                    Além disso, fazer o design de um sistema
                    é, geralmente, mais barato que construí-lo.
                </para>
                <para id="id84428">
                    <emphasis effect="italics">Design de
                        software estimula modelagem.</emphasis>
                    Ao modelar um sistema, o designer se
                    concentra no domínio do problema, ignorando
                    temporariamente detalhes menos significativos
                    para se alcançar a solução. Isso facilita
                    na separação da complexidade essencial
                    da complexidade acidental do problema.
                    E, como já dito por Brooks 
                    <link target-id="bid3"/>, essa separação
                    é benéfica para a qualidade final do
                    sistema projetado.
                </para>
                <para id="id84447">
                    <emphasis effect="italics">Design de
                        software envolve planejamento.</emphasis>
                    Uma vez que o design serve de guia
                    para a construção do sistema, o designer
                    deve então antecipar o que será necessário
                    para tanto. Esse planejamento ajuda
                    na estimativa dos diversos custos envolvidos
                    no desenvolvimento do sistema.
                </para>
                <example id="eip-207">
                    <label>Exemplo</label>
                    <title>Diferentes custos envolvidos
                        na construção de um sistema</title>
                    <list id="eip-493">
                        <item id="uid11">Quanto tempo durará
                            todo o desenvolvimento, </item>
                        <item id="uid12">Quantos desenvolvedores
                            serão necessários para o módulo
                            A, </item>
                        <item id="uid13">Se comprado, quanto
                            custará o módulo B, e se for
                            implementado, </item>
                        <item id="uid14">Ou qual será o
                            custo total do desenvolvimento
                            do sistema. </item>
                    </list>
                </example>
                <para id="id84520">
                    <emphasis effect="italics">Design de
                        software facilita a comunicação</emphasis>,
                    pois contém conhecimento sobre o sistema
                    que pode ser gravado, transmitido e
                    discutido entre os interessados.
                </para>
                <example id="eip-158">
                    <label>Exemplo</label>
                    <title>Casos do design de software
                        servindo como veículo de comunicação</title>
                    <para id="eip-0"> Ao apresentar um
                        sistema a novos membros de um time
                        de desenvolvimento, informações
                        valiosas, e.g., quais os principais
                        módulos e seus diversos comportamentos,
                        lhes podem ser passadas através
                        do design do sistema antes de mostrá-los
                        o código-fonte. Dessa maneira,
                        essas informações de alto nível
                        de abstração ajudarão a situá-los
                        no código posteriormente. </para>
                    <para id="eip-558">No entanto, o design
                        não serve apenas para os desenvolvedores.
                        Um usuário do sistema pode procurar
                        no design informações de um nível
                        ainda maior de abstração, e.g.,
                        quais funções o sistema é capaz
                        de realizar, ou qual o desempenho
                        delas.</para>
                </example>
                <para id="id84547">Por outro lado, design
                    de software também demanda algumas
                    observações importantes.</para>
                <para id="id84552">
                    <emphasis effect="italics">O problema
                        a ser resolvido pode não permanecer
                        o mesmo durante o processo de design.</emphasis>
                    Ao passo que o design é implementado,
                    o cliente, que é o interessado que
                    deseja o software construído para a
                    solução de um problema em particular,
                    (1) pode mudar de idéia quanto à natureza
                    do problema; (2) pode ter descrito
                    o problema incorretamente; ou ainda
                    (3) pode decidir que o problema mudou
                    ou mesmo que já fora resolvido enquanto
                    o design era projetado. Essas possibilidades
                    não devem ser ignoradas durante o desenvolvimento,
                    uma vez que elas podem ocasionar em
                    perda de tempo e dinheiro durante a
                    fase de design ou ainda ocasionar o
                    fracasso no atendimento das necessidades
                    do cliente.
                </para>
                <para id="id84566">
                    <emphasis effect="italics">Há diferenças
                        entre o design e o sistema construído
                        a partir dele.</emphasis> O design
                    de um software é apenas um modelo,
                    do qual o nível de detalhes pode não
                    ser adequado para certos tipos de avaliação.
                    Por sinal, avaliar um design insuficientemente
                    detalhado pode levar a resultados errôneos
                    e, conseqüentemente, a sistemas que
                    não resolvem os problemas da forma
                    esperada. Isso é comum acontecer, por
                    exemplo, quando se tenta avaliar desempenho
                    e maus designers não incluem detalhes
                    suficientes para esse tipo de avaliação.
                </para>
                <example id="eip-98">
                    <label>Exemplo</label>
                    <para id="eip-312"> Uma avaliação de
                        desempenho baseada num dado design
                        de um sistema atestou que esse
                        sistema seria capaz de arcar com
                        o acesso dez mil usuários simultâneos.
                        No entanto, esse design não detalhou
                        corretamente o quanto de recursos
                        cada usuário consome em cada acesso.
                        Assim, a avaliação do desempenho
                        considerou para cada ação de usuário
                        menos recursos do que seriam consumidos
                        na realidade. Como esperado, o
                        sistema em produção não suportou
                        os diversos acessos quando o número
                        de usuários simultâneos chegou
                        próximo ao limite esperado. </para>
                </example>
                <para id="id84589">Por mais eficaz que
                    um design seja, sua implementação pode
                    não ser. Por isso, devemos nos preparar
                    contra implementação divergente do
                    design, uma vez que ela pode resultar
                    num sistema que não alcança os objetivos
                    esperados da mesma forma que um design
                    insuficiente pode não alcançar.</para>
            </section>
        </section>
        <section id="cid2">
            <title>Elementos do processo de design de software</title>
            <para id="id84607">O processo de design pode
                ser descrito como o processo de escolha
                da representação de uma solução a partir
                de várias alternativas, dadas as restrições
                que um conjunto de objetivos envolve. Esse
                processo, ilustrado na 
                <link target-id="uid15"/>, pode ser dividido
                em duas fases 
                <link target-id="bid4"/>: 
                <emphasis effect="italics">diversificação</emphasis>
                e 
                <emphasis effect="italics">convergência</emphasis>.
            </para>
            <figure id="uid15">
                <label>Figura</label>
                <media id="uid15_media" alt="">
                    <image mime-type="image/png" src="designprocess.png" id="uid15_onlineimage" width="800">
                        <!-- NOTE: attribute width changes
                        image size online (pixels). original
                        width is 1124. -->
                    </image>
                    <image mime-type="application/postscript" src="designprocess.eps" id="uid15_printimage" print-width="10cm"/>
                </media>
                <caption>Ilustração do processo de design</caption>
            </figure>
            <para id="id84648">É durante a fase de diversificação
                em que as 
                <emphasis effect="italics">alternativas</emphasis>
                são geradas. Por alternativas, não nos
                referimos necessariamente a documentos
                descrevendo uma possível solução, mas também
                a idéias de solução. Essas alternativas
                são soluções em potencial e são geradas/obtidas
                a partir do conhecimento e da experiência
                do designer. Já na fase de convergência,
                o designer escolhe a alternativa (ou combinação
                de alternativas) que satisfaz(em) os 
                <emphasis effect="italics">objetivos</emphasis>
                esperados. A escolha comporá a 
                <emphasis effect="italics">solução</emphasis>
                que se sujeitará às 
                <emphasis effect="italics">restrições</emphasis>
                impostas pelo domínio do problema. Essa
                solução será descrita por meio de alguma
                <emphasis effect="italics">representação</emphasis>
                e essa representação escolhida deve estar
                de acordo com seus propósitos: descrever
                a solução e permitir a construção do sistema
                que melhor alcança os objetivos esperados.
            </para>
            <para id="id84689">Os elementos enfatizados
                no parágrafo anterior (objetivos, restrições,
                alternativas, representações e soluções),
                juntos, definem um arcabouço conceitual
                que nos ajuda a entender o processo de
                design de software 
                <link target-id="bid5"/>.
            </para>
            <section id="uid16">
                <title>Objetivos</title>
                <para id="id84709">O processo de design
                    tem início com uma necessidade. Se
                    algo é projetado, e conseqüentemente
                    construído, é porque o produto proveniente
                    do projeto suprirá essa necessidade.
                    Em Engenharia de Software, a necessidade
                    parte do cliente que especifica quais
                    suas necessidades e, portanto, quais
                    os objetivos a serem atingidos pelo
                    sistema de software a ser projetado.
                    Assim, o objetivo do processo de design
                    pode ser definido como:</para>
                <para id="id84718">
                    <definition id="objetivo-design-de-software">
                        <label>Definição</label>
                        <term>objetivo de design</term>
                        <meaning id="objetivo-design-de-software-significado">
                            Aquilo que se pretende alcançar
                            para resolver as necessidades
                            do cliente. </meaning>
                    </definition>
                </para>
                <para id="id84723">Em design de software,
                    objetivos também são chamados de requisitos.
                    O design se preocupa com dois tipos
                    de requisitos: requisitos funcionais
                    e requisitos não-funcionais. Um requisito
                    funcional especifica a funcionalidade
                    que um sistema exibe.</para>
                <para id="id84731">
                    <definition id="requisito-funcional">
                        <label>Definição</label>
                        <term>requisito funcional</term>
                        <meaning id="requisito-funcional-significado">
                            É a declaração de uma função
                            ou comportamento providos pelo
                            sistema sob condições específicas.
                            </meaning>
                    </definition>
                </para>
                <para id="id84737">Em outras palavras,
                    <emphasis effect="italics">o que</emphasis>
                    o sistema faz para alcançar às expectativas
                    do cliente. Por exemplo, um requisito
                    funcional de um programa de ordenação
                    de números pode ser descrita como sua
                    capacidade de ordenar inteiros; ou,
                    se estamos falando de um sistema de
                    informação de uma locadora de filmes
                    em DVD, temos como requisitos funcionais,
                    entre outros, a capacidade de buscar
                    um filme usando palavras-chave, a capacidade
                    de realizar o aluguel de um ou vários
                    DVDs, ou a capacidade de realizar a
                    devolução de um ou vários DVDs.
                </para>
                <para id="id84751">Por outro lado, um requisito
                    não-funcional, também chamado de atributo
                    de qualidade, especifica propriedades
                    ou características que o sistema de
                    software deve exibir diferentes dos
                    requisitos funcionais.</para>
                <para id="id84758">
                    <definition id="atributo-de-qualidade">
                        <label>Definição</label>
                        <term>atributo de qualidade (requisito
                            não-funcional)</term>
                        <meaning id="atributo-de-qualidade-significado">
                            É a descrição de propriedades,
                            características ou restrições
                            que o software apresenta exibidas
                            por suas funcionalidades. 
                            </meaning>
                    </definition>
                </para>
                <para id="id84764">Em outras palavras,
                    é basicamente 
                    <emphasis effect="italics">como</emphasis>
                    o sistema funcionará. De volta ao exemplo
                    do programa de ordenar números, um
                    atributo de qualidade que podemos mencionar
                    é o tempo de execução da função de
                    ordenação do sistema (e.g., é aceitável
                    que o tempo de execução do algoritmo
                    de ordenação tenha uma taxa de crescimento
                    de 
                    <m:math overflow="scroll">
                        <m:mrow>
                            <m:mi>O</m:mi>
                            <m:mo>(</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo form="prefix">log</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo>)</m:mo>
                        </m:mrow>
                    </m:math>, onde 
                    <emphasis effect="italics">n</emphasis>
                    é o tamanho da entrada). Já no sistema
                    da locadora de filmes, um exemplo de
                    atributo de qualidade é a exposição
                    de algumas de suas funcionalidades
                    via internet (e.g., busca e reserva
                    de filmes através de um 
                    <emphasis effect="italics">site</emphasis>
                    disponibilizado pelo sistema).
                </para>
                <para id="id84818">Como atributos de qualidade
                    têm um papel importante na arquitetura
                    do software, nós dedicaremos um capítulo
                    a eles, onde serão descritos, categorizados
                    e exemplificados em detalhes, além
                    de serem relacionados aos interessados
                    que os demandam.</para>
            </section>
            <section id="uid17">
                <title>Restrições</title>
                <para id="id84834">O produto de design
                    deve ser viável. Dessa maneira, restrições
                    são as regras, requisitos, relações,
                    convenções, ou princípios que definem
                    o contexto do processo de design, de
                    forma que seu produto seja viável.</para>
                <para id="id84841">
                    <definition id="restricao-de-design">
                        <label>Definição</label>
                        <term>restrição de design</term>
                        <meaning id="restricao-de-design-significado">
                            A regra, requisito, relação,
                            convenção, ou princípio que
                            define o texto do processo
                            de design. </meaning>
                    </definition>
                </para>
                <para id="id84847">É importante saber que
                    restrições são diretamente relacionadas
                    a objetivos e que, em alguns casos,
                    eles são intercambiáveis. No entanto,
                    uma vez que não são apenas os objetivos
                    que guiam o processo de design, é necessário
                    diferenciar objetivos de restrições.
                    Em outras palavras, um sistema pode
                    ter objetivos claros, mas seu design
                    ou algumas alternativas dele podem
                    ser inviáveis devido às restrições.</para>
                <para id="id84858">A seguir, apresentamos
                    dois exemplos que nos ajudarão a entender
                    o papel das restrições no design. No
                    primeiro exemplo, apesar de um sistema
                    ter um objetivo claro, seu design não
                    é viável devido a uma restrição.</para>
                <example id="eip-199">
                    <label>Exemplo</label>
                    <para id="eip-743"> Consideremos que
                        um cliente deseje um sistema com
                        um único objetivo: o sistema deve
                        decidir se um programa, cuja descrição
                        é informada como parâmetro de entrada,
                        termina sua execução ou não. </para>
                    <para id="eip-322423"> Um designer
                        inexperiente pode até tentar encontrar
                        alguma alternativa de design para
                        esse requisito – mas podemos ter
                        certeza que a tentativa será em
                        vão. Como é bem conhecido, há uma
                        restrição teórica em Ciência da
                        Computação, conhecida como o problema
                        da parada, que impede o desenvolvimento
                        de um programa capaz de alcançar
                        o objetivo proposto. Como essa
                        restrição impede a criação de qualquer
                        alternativa de design que satisfaça
                        o cliente, podemos observar que
                        um design pode ser se tornar inviável
                        mesmo que seus objetivos sejam
                        bem claros. </para>
                </example>
                <para id="id84889">Já no segundo exemplo,
                    o sistema também tem um objetivo claro.
                    No entanto, uma restrição torna uma
                    possibilidade de design inviável.</para>
                <example id="eip-914">
                    <label>Exemplo</label>
                    <para id="eip-1000"> Um cliente especifica
                        o seguinte requisito para seu sistema
                        de software: ele deve ser capaz
                        de ler dados de um leitor de cartões
                        de um modelo específico. No entanto,
                        ao estudar o requisito e, conseqüentemente,
                        o leitor de cartões, o designer
                        encontra a seguinte restrição.
                        O fabricante do leitor em questão
                        não o fornece driver necessário
                        para um dos sistemas operacionais
                        em que o sistema deve executar.
                        </para>
                    <para id="eip-1231231">Podemos observar
                        que, se não fosse por essa restrição,
                        o design para o módulo de entrada
                        de dados do sistema seria simples:
                        apenas dependeria do driver do
                        leitor para obter os dados dos
                        cartões. No entanto, agora o designer
                        terá que criar um design alternativo
                        para contornar a restrição encontrada.
                        Para isso, podemos citar algumas
                        possibilidades desse design. Uma
                        possibilidade seria emular um dos
                        sistemas operacionais suportados
                        quando o software estivesse executando
                        num s.o. não suportado. Isso significa
                        que seria necessária a criação
                        de uma camada de abstração entre
                        o driver do leitor e o sistema
                        operacional onde o software está
                        executando, onde essa camada representaria
                        o ambiente operacional suportado.
                        Essa camada de abstração, então,
                        seria implementada pelo sistema
                        nativo ou por um emulado, caso
                        o nativo fosse o não-suportado
                        pelo driver. Outra possibilidade
                        de design seria o projeto e implementação
                        do driver para o ambiente não-suportado.</para>
                </example>
                <para id="id84953">endexample</para>
            </section>
            <section id="uid18">
                <title>Alternativas</title>
                <para id="id84965">Uma alternativa de design
                    é uma possibilidade de solução. Uma
                    vez que problemas de design geralmente
                    possuem múltiplas soluções possíveis
                    <link target-id="bid1"/>, é comum que
                    sejam geradas mais de uma alternativa
                    para a solução de um único problema
                    ao menos em nível de conhecimento dos
                    designers. Note que o designer não
                    necessariamente documentará todas as
                    possibilidades de solução, mas, ao
                    menos, considerará algumas delas para
                    eleição de uma solução, mesmo que informalmente.
                </para>
                <para id="id84981">
                    <definition id="alternativa-de-design">
                        <label>Definição</label>
                        <term>alternativa de design</term>
                        <meaning id="alternativa-de-design-significado">
                            Uma possibilidade de solução
                            representada em nível de conhecimento.
                            </meaning>
                    </definition>
                </para>
                <para id="id84987">O que precisamos observar
                    é que o designer deve realizar duas
                    tarefas essenciais após entender os
                    objetivos e restrições envolvidos no
                    problema de design: gerar alternativas
                    de design e eleger a solução do problema
                    dentre as alternativas geradas.</para>
                <para id="id84994">A geração de alternativas
                    é o real desafio para os designers.
                    Diferente dos problemas de decisão,
                    onde alternativas são 
                    <emphasis effect="italics">conhecidas
                        ou buscadas</emphasis> através
                    de métodos conhecidos, problemas de
                    design pedem a 
                    <emphasis effect="italics">criação</emphasis>
                    de alternativas. O processo de criação
                    deve ser controlado por princípios
                    de design, pela experiência e imaginação
                    do designer 
                    <link target-id="bid5"/>. Alguns princípios
                    essenciais de design serão apresentados
                    ainda nesse capítulo.
                </para>
                <para id="id85020">Já a eleição da solução
                    é simplesmente a escolha de uma dentre
                    as alternativas geradas, desde que
                    essa sirva para a solução do problema.
                    A escolha da solução deve ser realizada
                    baseada em avaliações e experiência.</para>
                <para id="id85028">beginexample De volta
                    ao nosso programa de ordenação, consideremos
                    apenas uma de suas características:
                    o algoritmo de ordenação a ser usado,
                    e vamos observar quantas alternativas
                    um designer poderia gerar só a partir
                    dessa característica.</para>
                <para id="id85035">Uma rápida pesquisa
                    na internet retorna nove algoritmos
                    que respeitam o requisito imposto anteriormente
                    de crescimento do tempo de execução
                    (
                    <m:math overflow="scroll">
                        <m:mrow>
                            <m:mi>O</m:mi>
                            <m:mo>(</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo form="prefix">log</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo>)</m:mo>
                        </m:mrow>
                    </m:math>): 
                    <emphasis effect="italics">binary tree
                        sort</emphasis>, 
                    <emphasis effect="italics">heapsort</emphasis>,
                    <emphasis effect="italics">in-place
                        merge sort</emphasis>, 
                    <emphasis effect="italics">introsort</emphasis>,
                    <emphasis effect="italics">library
                        sort</emphasis>, 
                    <emphasis effect="italics">merge sort</emphasis>,
                    <emphasis effect="italics">quicksort</emphasis>,
                    <emphasis effect="italics">smoothsort</emphasis>,
                    <emphasis effect="italics">strand sort</emphasis>.
                    Assim, esses nove algoritmos poderiam
                    ser transformados em nove alternativas
                    de design. Adicionalmente, um designer
                    mais experiente em ordenação saberia
                    que os dados de entrada podem definir
                    o desempenho real do algoritmo, uma
                    vez que uma das alternativas pode ter
                    um ótimo desempenho para uma determinada
                    entrada, enquanto outra alternativa,
                    ainda que respeitando o mesmo 
                    <m:math overflow="scroll">
                        <m:mrow>
                            <m:mi>O</m:mi>
                            <m:mo>(</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo form="prefix">log</m:mo>
                            <m:mi>n</m:mi>
                            <m:mo>)</m:mo>
                        </m:mrow>
                    </m:math>, pode ter um péssimo desempenho
                    para a mesma entrada. Assim, ele definiria
                    que dois algoritmos serão usados no
                    design, de forma que, de acordo com
                    os dados de entrada, o algoritmo de
                    melhor desempenho real para esses dados
                    seja escolhido em tempo de execução.
                    Assim, ainda mais alternativas de design
                    são geradas. endexample
                </para>
                <para id="id85142">Devemos observar que
                    a geração de alternativas poderia continuar
                    indefinidamente caso o designer considerasse
                    outros aspectos do problema. Dessa
                    maneira, 
                    <emphasis effect="italics">quando parar</emphasis>
                    a geração de alternativas é um problema
                    também a ser resolvido pelo designer,
                    uma vez que problemas de design geralmente
                    têm um número infinito de soluções
                    em potencial. Essa noção de quando
                    parar o processo de geração de alternativas,
                    certamente, é adquirida com a experiência.
                </para>
            </section>
            <section id="uid19">
                <title>Representações</title>
                <para id="id85168">A representação é a
                    linguagem do design. Apesar do real
                    produto do processo de design ser a
                    representação de um sistema de software
                    que possibilita sua construção, descrever
                    o sistema não é o único propósito das
                    representações. A representação também
                    facilita o próprio processo de design,
                    uma vez que ajuda na comunicação dos
                    interessados e também serve como registro
                    das decisões tomadas.</para>
                <para id="id85177">
                    <definition id="representacao-de-design">
                        <label>Definição</label>
                        <term>representação de design</term>
                        <meaning id="representacao-de-design-significado">
                            A linguagem do processo de
                            design que representa o produto
                            do design para sua construção
                            e também dá suporte ao processo
                            de design como um todo.</meaning>
                    </definition>
                </para>
                <para id="id85183">A representação facilita
                    a comunicação porque torna as alternativas
                    em produtos manipuláveis, que podem
                    ser comunicados, avaliados, e discutidos,
                    não só por seus criadores, mas também
                    por outros interessados.</para>
                <para id="id85190">É importante observar
                    que existem diversas dimensões a serem
                    representadas numa única alternativa
                    de design. Essas dimensões abrangem
                    comportamento, estrutura, relações
                    entre entidades lógicas e entidades
                    físicas, entre outros. Essas dimensões
                    são normalmente descritas em diferentes
                    tipos de representações, que, em outro
                    momento, serão chamadas de 
                    <emphasis effect="italics">visões</emphasis>.
                </para>
                <para id="id85205">Para exemplificar representações
                    de design, apresentaremos duas dimensões
                    derivadas do nosso programa-exemplo
                    de ordenação usando duas representações
                    diferentes. A primeira representação,
                    ilustrada pela 
                    <link target-id="uid20"/>, mostra a
                    dimensão estrutural de uma alternativa
                    de design usando 
                    <emphasis effect="italics">Unified
                        Modeling Language</emphasis> (UML)
                    <link target-id="bid6"/>. Examinando
                    essa representação, podemos observar
                    como a solução foi decomposta em classes
                    funcionais, como as diversas classes
                    da estrutura se relacionam entre si,
                    ou até em que pontos poderíamos reusar
                    pedaços de software prontos para a
                    construção, desde que implementem as
                    mesmas interfaces descritas na representação.
                    No entanto, devemos também observar
                    que essa representação não é autocontida,
                    uma vez que é necessário conhecimento
                    em UML para entendê-la completamente.
                </para>
                <figure id="uid20">
                    <label>Figura</label>
                    <media id="uid20_media" alt="">
                        <image mime-type="image/png" src="sorting-class-diagram.png" id="uid20_onlineimage" width="290">
                            <!-- NOTE: attribute width
                            changes image size online (pixels).
                            original width is 290. -->
                        </image>
                        <image mime-type="application/postscript" src="sorting-class-diagram.eps" id="uid20_printimage" print-width="8cm"/>
                    </media>
                    <caption>Representação estrutural do
                        programa de ordenação</caption>
                </figure>
                <para id="id85246">Já a segunda representação,
                    <link target-id="uid21"/>, mostra parte
                    do comportamento do programa de ordenação
                    com alto nível de detalhe. Apesar de
                    não conseguirmos extrair dessa representação
                    a mesma informação apresentada na figura
                    anterior, essa nos permite analisar
                    seu comportamento assimtoticamente
                    em relação ao crescimento do tamanho
                    dos dados de entrada. Além disso, podemos
                    também analisar o espaço consumido
                    na execução do algoritmo.
                </para>
                <figure id="uid21">
                    <label>Figura</label>
                    <media id="uid21_media" alt="">
                        <image mime-type="image/png" src="sort-pseudocode.png" id="uid21_onlineimage" width="401">
                            <!-- NOTE: attribute width
                            changes image size online (pixels).
                            original width is 401. -->
                        </image>
                        <image mime-type="application/postscript" src="sort-pseudocode.eps" id="uid21_printimage" print-width="8cm"/>
                    </media>
                    <caption>Pseudocódigo do Merge sort
                        <link target-id="bid7"/>
                    </caption>
                </figure>
                <para id="id85276">Ambas as representações
                    mostram aspectos importantes do design
                    de um software. No entanto, as pessoas
                    envolvidas no seu desenvolvimento podem
                    ainda estar interessadas em outros
                    aspectos além da estrutura ou análise
                    assimtótica do algoritmo. Dessa maneira,
                    outras representações podem ainda ser
                    necessárias para mostrar outros aspectos
                    do sistema, e é papel do processo de
                    design – e do designer – provê-las.</para>
                <para id="id85285">Por fim, se considerarmos
                    múltiplas versões ao longo do tempo
                    de uma única representação, poderemos
                    observar a evolução das decisões de
                    design feitas ao longo desse período.
                    Assim, se considerarmos as diversas
                    versões obtidas até se alcançar o algoritmo
                    descrito na 
                    <link target-id="uid21"/>, perceberemos
                    a evolução desde o 
                    <emphasis effect="italics">merge sort</emphasis>
                    padrão até o 
                    <emphasis effect="italics">merge sort
                        in-place</emphasis> considerado
                    pelo designer. Então, o histórico do
                    design se torna peça fundamental para
                    se entender quais decisões passadas
                    levaram ao estado atual do design –
                    e do sistema.
                </para>
            </section>
            <section id="uid22">
                <title>Soluções</title>
                <para id="id85320">Uma solução do design
                    não é nada além do que a descrição
                    que permite desenvolvedores construir
                    um sistema de software a partir dos
                    detalhes especificados por uma ou diversas
                    representações. Suas principais características
                    serão descritas nos parágrafos a seguir.</para>
                <para id="id85328">
                    <definition id="solucao-de-design">
                        <label>Definição</label>
                        <term>solução do design</term>
                        <meaning id="solucao-de-design-significado">
                            A descrição do design que permite
                            a construção do sistema de
                            software que alcança os objetivos
                            do design.</meaning>
                    </definition>
                </para>
                <para id="id85334">
                    <emphasis effect="italics">Soluções
                        de design refletem a complexidade
                        do problema</emphasis>, geralmente
                    por mostrar diversos elementos e relações
                    que compõem o problema. É possível
                    observar essa característica quando,
                    por exemplo, fazendo o design do sistema
                    de informação de uma locadora que já
                    mencionamos anteriormente. Qualquer
                    que seja a solução, ela conterá elementos
                    como filmes, DVDs, clientes, gêneros
                    de filmes, etc. Todos eles inerentes
                    ao problema em questão. No entanto,
                    só os elementos não são o bastante
                    para compor a solução. A solução deve
                    também conter relações do tipo: “um
                    cliente pode alugar um ou mais DVDs”,
                    “um filme pode ter um ou mais gêneros”,
                    ou “um DVD pode conter um ou mais filmes”.
                    Em outras palavras, a solução deve
                    conter relações similares às relações
                    encontradas no domínio do problema.
                    Por fim, quando diversos elementos
                    têm diversas relações diferentes entre
                    si, a complexidade emerge.
                </para>
                <para id="id85358">
                    <emphasis effect="italics">É difícil
                        validar soluções de design.</emphasis>
                    A complexidade inerente ao problema
                    faz surgir diversos pontos de possível
                    validação em relação aos objetivos
                    de design. No entanto, o problema reside
                    na precisão da descrição dos objetivos.
                    Normalmente, para problemas complexos,
                    objetivos são descritos num alto-nível
                    de abstração que dificulta ou impossibilita
                    bastante a avaliação das soluções.
                </para>
                <para id="id85372">E, por fim, 
                    <emphasis effect="italics">a maioria
                        dos problemas de design aceita
                        diversas soluções.</emphasis> Isso
                    é algo natural a problemas de design:
                    uma vez que diversas alternativas podem
                    ser geradas a partir de um único problema
                    de design, diversas soluções podem
                    ser obtidas 
                    <link target-id="bid1"/>.
                </para>
            </section>
        </section>
        <section id="cid3">
            <title>Níveis de design de software</title>
            <para id="id85400">O produto do processo de
                design é sempre uma solução de design.
                No entanto, apesar de ser uma descrição
                que permite a construção do sistema, nada
                é dito sobre o nível de detalhe contido
                nessa solução. Na verdade, o design pode
                acontecer em diversos níveis de detalhe.</para>
            <para id="id85408">De acordo com o Guia para
                o Corpo de Conhecimento de Engenharia de
                Software 
                <link target-id="bid8"/>, o processo de
                design de software consiste em duas atividades:
                <emphasis effect="italics">design de alto
                    nível</emphasis> e 
                <emphasis effect="italics">design detalhado</emphasis>.
            </para>
            <para id="id85429">O design de alto nível,
                também conhecido como design arquitetural,
                trata de descrever a organização fundamental
                do sistema, identificando seus diversos
                módulos (e sua relações entre si e com
                o ambiente) para que se alcancem os objetivos
                propostos pelo cliente.</para>
            <para id="id85437">
                <definition id="design-arquitetural">
                    <label>Definição</label>
                    <term>design arquitetural</term>
                    <meaning id="design-arquitetural-significado">
                        Descreve como o software é decomposto
                        e organizado em módulos e suas
                        relações.</meaning>
                </definition>
            </para>
            <para id="id85442">Ao contrário do design de
                alto nível, o design detalhado se preocupa
                com a descrição detalhada de cada módulo
                possibilitando a construção e se adequando
                ao design de alto nível.</para>
            <para id="id85449">
                <definition id="design-detalhado">
                    <label>Definição</label>
                    <term>design detalhado</term>
                    <meaning id="design-detalhado-significado">
                        Descreve o comportamento específico
                        e em detalhes dos módulos que compõem
                        o design arquitetural. </meaning>
                </definition>
            </para>
            <para id="id85455">Apesar dessa divisão conceitual
                de design em duas atividades, essa divisão
                pode não acontecer durante o processo de
                desenvolvimento do software. Algumas vezes,
                o designer – ou quem assume seu papel –
                realiza ambas as atividades em paralelo,
                concebendo assim um produto de design que
                permitirá tanto o alcance dos requisitos
                de qualidade, quanto a construção precisa
                do sistema por meio de seus detalhes. No
                entanto, adotaremos a separação conceitual
                das duas atividades de forma que possamos
                nos focar no design arquitetural, que é
                o principal assunto desse livro e que será
                discutido nos próximos capítulos.</para>
            <para id="id85463">No entanto, antes de iniciarmos
                nossos estudos em Arquitetura de Software,
                gostaríamos de lembrar alguns princípios
                e técnicas essenciais ao design de software.</para>
        </section>
        <section id="cid4">
            <title>Princípios e técnicas de design de software</title>
            <para id="id85480">Há diversos princípios,
                técnicas, e abordagens nessa área que geralmente
                resultam em bons produtos de design de
                software. Uma vez que há muitos livros
                e artigos sobre esse assunto, gostaríamos
                apenas de fazer uma breve exposição do
                assunto nessa seção, contribuindo assim
                com referências para textos mais abrangentes.
                Os princípios, técnicas e abordagens essenciais
                para um designer que apresentaremos são
                as seguintes:</para>
            <list id="id85488" display="block" list-type="bulleted">
                <item id="uid23">Abstração </item>
                <item id="uid24">Encapsulamento </item>
                <item id="uid25">Modularização </item>
                <item id="uid26">Separação de preocupações
                    </item>
                <item id="uid27">Acoplamento e coesão </item>
                <item id="uid28">Separação de políticas
                    da execução de algoritmos </item>
                <item id="uid29">Separação de interfaces
                    de suas implementações </item>
            </list>
            <section id="uid30">
                <title>Abstração</title>
                <para id="id85583">Abstração é um princípio
                    essencial para se lidar com complexidade.
                    Esse princípio recomenda que um elemento
                    que compõe o design deva ser representado
                    apenas por suas características essenciais,
                    de forma que permita a distinção de
                    outros elementos por parte do observador
                    <link target-id="bid9"/>. Como resultado,
                    temos a representação de um elemento
                    do design mais simples, uma vez que
                    detalhes desnecessários são descartados,
                    facilitando então o entendimento, comunicação
                    e avaliação.
                </para>
                <para id="id85600">O que poderemos observar
                    é que a maioria das técnicas empregadas
                    por designers ajudam na elevação do
                    nível de abstração do design e, assim,
                    baixam o nível de complexidade da solução.</para>
            </section>
            <section id="uid31">
                <title>Encapsulamento</title>
                <para id="id85615">Encapsulamento está
                    relacionado à ocultação de detalhes
                    de implementação de um elemento de
                    um sistema aos que usarão esse elemento
                    <link target-id="bid10"/>. Fazendo
                    isso, o acoplamento entre os elementos
                    é minimizado e sua contribuição para
                    a complexidade do sistema é restringida
                    às informações que eles expõem.
                </para>
                <para id="id85629">Encapsulamento pode
                    ser obtido de diferentes maneiras:
                    modularizando o sistema, separando
                    suas preocupações, separando interfaces
                    de implementações, ou separando políticas
                    da execução de algoritmos.</para>
            </section>
            <section id="uid32">
                <title>Modularização</title>
                <para id="id85645">Modularização é a decomposição
                    significativa do sistema em módulos.
                    A modularização introduz partições
                    bem-definidas e documentadas ao sistema
                    ao decidir como estruturas lógicas
                    do sistema serão divididas fisicamente.
                    Podemos citar alguns benefícios da
                    modularização:</para>
                <list id="id85653" display="block" list-type="bulleted">
                    <item id="uid33">Facilita o entendimento,
                        uma vez que cada módulo pode ser
                        estudado separadamente; </item>
                    <item id="uid34">Facilita o desenvolvimento,
                        uma vez que cada módulo pode ser
                        projetado, implementado e testado
                        separadamente; </item>
                    <item id="uid35">Diminui o tempo de
                        desenvolvimento, uma vez que módulos
                        podem ser implementados em paralelo,
                        ou ainda reusados; e </item>
                    <item id="uid36">Promove a flexibilidade
                        no produto, uma vez que um módulo
                        pode ser substituído por outro,
                        desde que implemente as mesmas
                        interfaces. </item>
                </list>
            </section>
            <section id="uid37">
                <title>Separação de preocupações</title>
                <para id="id85721">A separação de preocupações
                    está fortemente ligada ao princípio
                    da modularização. De certa maneira,
                    a separação de preocupações define
                    a regra para definir os módulos de
                    um sistema: preocupações diferentes
                    ou não-relacionadas devem se restringir
                    a módulos diferentes. Assim, separando
                    preocupações, obtemos benefícios semelhantes
                    aos da modularização.</para>
            </section>
            <section id="uid38">
                <title>Acoplamento e coesão</title>
                <para id="id85739">Acoplamento e coesão
                    são princípios usados para medir se
                    módulos de um design foram bem divididos.</para>
                <para id="id85744">Acoplamento é a medida
                    de interdependência entre módulos de
                    software. Ou seja, quanto mais dependente
                    um módulo A é da implementação do módulo
                    B, maior é o acoplamento entre os módulos
                    A e B. Alto acoplamento implica que
                    (1) os módulos envolvidos serão mais
                    difíceis de entender, uma vez que precisam
                    ser entendidos em conjunto; (2) os
                    módulos envolvidos serão mais difíceis
                    de modificar, uma vez que as mudanças
                    impactarão mais de um módulo; e (3)
                    os módulos envolvidos serão mais difíceis
                    de manter, uma vez que um problema
                    num módulo se espalhará pelos módulos
                    com quem está altamente acoplados.</para>
                <para id="id85753">Por outro lado, coesão
                    é uma medida intramódulo. Ela é a medida
                    da relação entre tarefas realizadas
                    dentro de um mesmo módulo. As tarefas
                    de um módulo podem estar relacionadas
                    entre si por diferentes motivos. Esses
                    motivos são usados para classificar
                    os diferentes tipos de coesão:</para>
                <list id="id85761" display="block" list-type="labeled-item">
                    <item id="uid39">
                        <label>
                            <emphasis effect="italics">Coesão
                                funcional</emphasis>:
                        </label>as tarefas estão agrupadas
                        por suas funções serem similares.
                        
                    </item>
                    <item id="uid40">
                        <label>
                            <emphasis effect="italics">Coesão
                                seqüencial</emphasis>:
                        </label>as tarefas estão agrupadas
                        por elas pertencerem à mesma seqüência
                        de operações. Elas compartilham
                        dados a cada etapa da seqüência,
                        mas não realizam uma operação completa
                        quando executadas juntas. 
                    </item>
                    <item id="uid41">
                        <label>
                            <emphasis effect="italics">Coesão
                                comunicativa</emphasis>:
                        </label>as tarefas estão agrupadas
                        porque usam os mesmos dados, mas
                        não estão relacionadas de nenhuma
                        outra maneira. 
                    </item>
                    <item id="uid42">
                        <label>
                            <emphasis effect="italics">Coesão
                                temporal</emphasis>:
                        </label>as tarefas estão agrupadas
                        por serem executadas no mesmo intervalo
                        de tempo. 
                    </item>
                    <item id="uid43">
                        <label>
                            <emphasis effect="italics">Coesão
                                procedural</emphasis>:
                        </label>as tarefas estão agrupadas
                        porque elas devem ser executadas
                        numa ordem específica. 
                    </item>
                    <item id="uid44">
                        <label>
                            <emphasis effect="italics">Coesão
                                lógica</emphasis>:
                        </label>as tarefas estão agrupadas
                        por compartilharem uma mesma 
                        <emphasis effect="italics">flag</emphasis>
                        de controle, que indicará qual
                        tarefa será realizada durante a
                        execução do sistema. 
                    </item>
                    <item id="uid45">
                        <label>
                            <emphasis effect="italics">Coesão
                                coincidente</emphasis>:
                        </label>as tarefas estão agrupadas
                        sem qualquer critério. 
                    </item>
                </list>
                <para id="id85907">Para alcançarmos bons
                    designs, podemos ordenar os tipos de
                    coesão dos mais desejáveis para os
                    menos desejáveis 
                    <link target-id="bid11"/>: funcional,
                    seqüencial, comunicativa, temporal,
                    procedural, lógica, e coincidente.
                </para>
            </section>
            <section id="uid46">
                <title>Separação de Políticas e Execução
                    de Algoritmos</title>
                <para id="id85930">Essa técnica realiza
                    a separação de preocupações. Essa técnica
                    dita uma abordagem simples de divisão
                    de preocupações: ou um módulo deve
                    se preocupar com as decisões sensíveis
                    a contexto ou com a execução de algoritmos,
                    mas não ambos 
                    <link target-id="bid10"/>. Em outras
                    palavras, alguns módulos devem apenas
                    executar algoritmos sem fazer qualquer
                    decisão sensível a contexto. Essas
                    decisões devem ser deixadas para os
                    módulos específicos para realização
                    dessas decisões e que também serão
                    responsáveis por suprir parâmetros
                    para os módulos de execução de algoritmos.
                </para>
                <para id="id85948">Essa separação facilita
                    o reuso e manutenção, principalmente
                    dos módulos de algoritmos, uma vez
                    que eles são menos específicos que
                    os módulos de decisões sensíveis a
                    contexto.</para>
            </section>
            <section id="uid47">
                <title>Separação de Interfaces de suas
                    Implementações</title>
                <para id="id85965">A separação entre interfaces
                    e implementações também beneficia a
                    modularização. Essa técnica recomenda
                    a descrição da funcionalidade a ser
                    implementada por algum módulo por meio
                    de contratos, chamados interfaces.
                    Assim, os módulos implementarão as
                    interfaces de forma a comporem o sistema.</para>
                <para id="id85973">Usando essa técnica,
                    o acoplamento entre módulos e seus
                    clientes é diminuído, uma vez que os
                    clientes estarão ligados apenas a interfaces
                    – e não implementações –, e benefícios
                    como facilidade no reuso, melhor entendimento
                    do código, e menor custo de manutenção
                    são alcançados.</para>
            </section>
        </section>
        <section id="id85982">
            <title>Resumo</title>
            <para id="id85999">Esse capítulo expôs o conhecimento
                necessário sobre Design de Software para
                o estudo de Arquitetura de Software. Espera-se
                que, ao final desse capítulo, o leitor
                saiba:</para>
            <list id="id86005" display="block" list-type="bulleted">
                <item id="uid48">o que é design software,
                    seja como produto ou como processo,
                    e quais são suas características e
                    benefícios; </item>
                <item id="uid49">como os problemas de design
                    de software podem ser decompostos;
                    e </item>
                <item id="uid50">o que são os princípios
                    e técnicas de design de software e
                    quais seus benefícios. </item>
            </list>
            <para id="id86048">Pela existência de ótimos
                livros sobre Design de Software já escritos
                tendo em vista o mesmo público-alvo que
                nós (o leitor ainda inexperiente), nós
                preferimos não nos aprofundar nos assuntos
                expostos nesse capítulo, uma vez que nossa
                intenção foi de apenas introduzi-los. Para
                informações mais detalhadas, recomendamos
                os livros sobre Design de Software referenciados
                na bibliografia desse capítulo.</para>
        </section>
        <section id="id86057">
            <title>Exercícios</title>
            <exercise id="eip-788">
                <label>Exercício</label>
                <problem id="eip-238">
                    <para id="eip-583"> Quais os benefícios
                        de se projetar sistemas? </para>
                </problem>
            </exercise>
            <exercise id="eip-619">
                <label>Exercício</label>
                <problem id="eip-950">
                    <para id="eip-698"> Duas fases importantes
                        do projeto de software são as fases
                        de Divergência e Convergência.
                        Descreva o que é feito em cada
                        fase. </para>
                </problem>
            </exercise>
            <exercise id="eip-900">
                <label>Exercício</label>
                <problem id="eip-188">
                    <para id="eip-345"> Jack Reeves, em
                        <emphasis effect="italics">What
                            is Software Design? </emphasis>
                        <link target-id="bid12"/>, afirma
                        que o código fonte é design. Qual
                        a sua opinião a respeito da afirmativa?
                        
                    </para>
                </problem>
            </exercise>
            <exercise id="eip-61">
                <label>Exercício</label>
                <problem id="eip-225">
                    <para id="eip-572"> Qual padrão de
                        projeto viabiliza a separação de
                        política e implementação? </para>
                </problem>
            </exercise>
            <exercise id="eip-9">
                <label>Exercício</label>
                <problem id="eip-127">
                    <para id="eip-418"> Defina para coesão
                        e acoplamento e sugira métricas
                        para medi-las em software. </para>
                </problem>
            </exercise>
        </section>
    </content>
    <bib:file>
        <bib:entry id="bid8">
            <bib:book>
                <!--required fields-->
                <bib:author>Abran, Alain and Moore, James
                    W. and Bourque, Pierre and Dupuis,
                    Robert and Tripp, Leonard L.</bib:author>
                <bib:title>Guide to the Software Engineering
                    Body of Knowledge (SWEBOK)</bib:title>
                <bib:publisher>IEEE</bib:publisher>
                <bib:year>2004</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month/>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid4">
            <bib:incollection>
                <!--required fields-->
                <bib:author>Belady, L.</bib:author>
                <bib:title>Foreword</bib:title>
                <bib:booktitle>Software Design: Methods
                    and Techniques (L.J. Peters, author)</bib:booktitle>
                <bib:publisher>Yourdon Press</bib:publisher>
                <bib:year>1981</bib:year>
                <!--optional fields-->
                <bib:editor/>
                <bib:number/>
                <bib:series/>
                <bib:type/>
                <bib:chapter/>
                <bib:pages/>
                <bib:address/>
                <bib:edition/>
                <bib:month/>
                <bib:note/>
            </bib:incollection>
        </bib:entry>
        <bib:entry id="bid9">
            <bib:book>
                <!--required fields-->
                <bib:author>Booch, Grady and Maksimchuk,
                    Robert A. and Engel, Michael W. and
                    Young, Bobbi J. and Conallen, Jim and
                    Houston, Kelli A.</bib:author>
                <bib:title>Object-Oriented Analysis and
                    Design with Applications (3rd Edition)</bib:title>
                <bib:publisher>Addison-Wesley Professional</bib:publisher>
                <bib:year>2007</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month>April</bib:month>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid10">
            <bib:book>
                <!--required fields-->
                <bib:author>Buschmann, Frank and Meunier,
                    Regine and Rohnert, Hans and Sommerlad,
                    Peter and Stal, Michael and Sommerlad,
                    Peter and Stal, Michael</bib:author>
                <bib:title>Pattern-Oriented Software Architecture,
                    Volume 1: A System of Patterns</bib:title>
                <bib:publisher>John Wiley &amp; Sons</bib:publisher>
                <bib:year>1996</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month>August</bib:month>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid3">
            <bib:book>
                <!--required fields-->
                <bib:author>Brooks, Frederick P.</bib:author>
                <bib:title>The Mythical Man-Month: Essays
                    on Software Engineering, 20th Anniversary
                    Edition</bib:title>
                <bib:publisher>Addison-Wesley Professional</bib:publisher>
                <bib:year>1995</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month>August</bib:month>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid1">
            <bib:book>
                <!--required fields-->
                <bib:author>Budgen, David</bib:author>
                <bib:title>Software Design (2nd Edition)</bib:title>
                <bib:publisher>Addison Wesley</bib:publisher>
                <bib:year>2003</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month>May</bib:month>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid2">
            <bib:book>
                <!--required fields-->
                <bib:editor/>
                <bib:title>IEEE Standard Computer Dictionary:
                    Compilation of IEEE Standard Computer
                    Glossaries</bib:title>
                <bib:publisher>Institute of Electrical
                    and Electronics Engineers Inc., The</bib:publisher>
                <bib:year>1991</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month/>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid11">
            <bib:book>
                <!--required fields-->
                <bib:author>Mcconnell, Steve</bib:author>
                <bib:title>Code Complete, Second Edition</bib:title>
                <bib:publisher>Microsoft Press</bib:publisher>
                <bib:year>2004</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:series/>
                <bib:address/>
                <bib:edition/>
                <bib:month>June</bib:month>
                <bib:note/>
            </bib:book>
        </bib:entry>
        <bib:entry id="bid6">
            <bib:misc>
                <!--required fields-->
                <!--optional fields-->
                <bib:author>Object Management Group, Inc.,
                    </bib:author>
                <bib:title>Unified Modeling Language</bib:title>
                <bib:howpublished>http://www.uml.org</bib:howpublished>
                <bib:month>September</bib:month>
                <bib:year>2008</bib:year>
                <bib:note/>
            </bib:misc>
        </bib:entry>
        <bib:entry id="bid12">
            <bib:article>
                <!--required fields-->
                <bib:author>Reeves, Jack W.</bib:author>
                <bib:title>What is Software Design?</bib:title>
                <bib:journal>C++ Journal</bib:journal>
                <bib:year>1992</bib:year>
                <!--optional fields-->
                <bib:volume/>
                <bib:number/>
                <bib:pages/>
                <bib:month/>
                <bib:note/>
            </bib:article>
        </bib:entry>
        <bib:entry id="bid5">
            <bib:article>
                <!--required fields-->
                <bib:author>Smith, G. F. and Browne, G.
                    J.</bib:author>
                <bib:title>Conceptual Foundations of Design
                    Problem Solving</bib:title>
                <bib:journal>Systems, Man and Cybernetics,
                    IEEE Transactions on</bib:journal>
                <bib:year>1993</bib:year>
                <!--optional fields-->
                <bib:volume>23</bib:volume>
                <bib:number>5</bib:number>
                <bib:pages>1209–1219</bib:pages>
                <bib:month/>
                <bib:note/>
            </bib:article>
        </bib:entry>
        <bib:entry id="bid0">
            <bib:inproceedings>
                <!--required fields-->
                <bib:author>Taylor, Richard N. and van
                    der Hoek, Andre</bib:author>
                <bib:title>Software Design and Architecture
                    – The Once and Future Focus of Software
                    Engineering</bib:title>
                <bib:booktitle>FOSE '07: 2007 Future of
                    Software Engineering</bib:booktitle>
                <bib:year>2007</bib:year>
                <!--optional fields-->
                <bib:editor/>
                <bib:number/>
                <bib:series/>
                <bib:pages>226–243</bib:pages>
                <bib:address>Washington, DC, USA</bib:address>
                <bib:month/>
                <bib:organization/>
                <bib:publisher>IEEE Computer Society</bib:publisher>
                <bib:note/>
            </bib:inproceedings>
        </bib:entry>
        <bib:entry id="bid7">
            <bib:misc>
                <!--required fields-->
                <!--optional fields-->
                <bib:author>Wikipedia, </bib:author>
                <bib:title>Merge Sort – Wikipedia, The
                    Free Encyclopedia</bib:title>
                <bib:howpublished/>
                <bib:month/>
                <bib:year>2008</bib:year>
                <bib:note>[Online; accessed 2-September-2008]</bib:note>
            </bib:misc>
        </bib:entry>
    </bib:file>
</document>
