O único objetivo de um software é o de atender a seus requisitos. Esses requisitos são definidos ao longo de seu ciclo desenvolvimento e costumam ser classificados em requisitos funcionais e requisitos não-funcionais.
Os requisitos funcionais descrevem as funções que o sistema é capaz de realizar, ou seja, descrevem o que o sistema faz.
- Definição 1: requisito funcional
- É a declaração de uma função ou comportamento providos pelo sistema sob condições específicas.
Os requisitos do software são impostos pelos seus diversos stakeholders. No entanto, os requisitos funcionais costumam ser ditados pelos clientes do software, afinal são eles que esperam ter seus problemas resolvidos pelas funcionalidades do software.
Exemplo 1
Se estamos falando do SASF, entre suas funções, podemos citar:
- (RF-01): O usuário deve ser capaz de inserir um filme da sua lista de aluguéis;
- (RF-03): O usuário deve ser capaz de assistir a um filme via streaming;
- (RF-06): O usuário deve ser capaz de adicionar um comentário sobre um filme.
Se o problema de desenvolver software fosse apenas o de atender aos requisitos funcionais, desenvolver software já poderia ser considerado uma tarefa difícil. Isso porque, para serem atendidos, muitos dos requisitos funcionais necessitam de conhecimento que ultrapassa os limites da Engenharia de Software, da Ciência da Computação ou mesmo da Matemática. Afinal, para se implementar sistemas para Computer-Aided Design (CAD) ou sistemas que analisam os dados extraídos do Large Hadron Collider (LHC) 1 é preciso grande conhecimento específico ao domínio do problema, ou seja, grande conhecimento de outras engenharias ( por ex., Engenharia Mecânica e Civil) ou de outras ciências ( por ex., Física e Química), respectivamente.
Além da necessidade de conhecimento específico ao domínio do problema, há outra dificuldade no desenvolvimento de software para atender apenas aos requisitos funcionais: o cliente pode não ter certeza sobre o que ele quer do software. Esta condição é bem conhecida pela Engenharia de Requisitos, que nos provê algumas técnicas para resolvê-la ou contorná-la. Mas isso não quer dizer que não possa se tornar um problema durante o ciclo desenvolvimento. Afinal, se o principal interessado não sabe bem quais funções se espera que o sistema realize, não podemos afirmar que será fácil desenvolver esse sistema.
Por outro lado, há também os requisitos não-funcionais. Esses estão relacionados à qualidade da realização dos requisitos funcionais, ou seja, como essas funções são realizadas.
- Definição 2: requisito não-funcional
- É a descrição de propriedades, características ou restrições que o software apresenta exibidas por suas funcionalidades.
Esses requisitos também são impostos pelos diversos stakeholders do software e estão normalmente relacionados a interfaces com o usuário, capacidades, consumo de recursos e escalas de tempo.
Exemplo 2
Podemos citar alguns exemplos de requisitos não-funcionais do SASF:
- (RNF-01): O sistema deve permitir o uso por diversas interfaces diferentes: navegador de internet, celular, TV (usando um decodificador de TV por assinatura compatível) e aplicação-cliente compatível com as famílias de sistemas operacionais Windows, Mac OS e Linux;
- (RNF-04): O sistema deve suportar até 3 milhões de inserções na fila de aluguéis por dia (34,7 operações por segundo);
- (RNF-09): Uma transmissão de vídeo via streaming não pode ser iniciada em mais do que 30 segundos.
As restrições feitas pelos requisitos não-funcionais são várias e podem incluir restrições ao processo de desenvolvimento, restrições para atingir ou manter compatibilidade, e restrições legais, econômicas ou de interoperabilidade. As restrições ao processo de desenvolvimento podem ser feitas pela imposição de padrões de desenvolvimento ou mesmo de linguagens a serem utilizadas pelo sistema. Por exemplo, um requisito não-funcional de um sistema pode ser que ele deva ser implementado usando a linguagem Java™, uma vez que a equipe responsável pela operação e manutenção após seu desenvolvimento seja é experiente nessa linguagem. Por fim, podemos ainda citar requisitos não-funcionais conhecidos que foram impostos em prol de compatibilidade e interoperabilidade e – por que não dizer – de questões econômicas, que é um caso relacionado ao sistema operacional Windows NT. O Windows NT possui requisitos não-funcionais que ditam que ele deve ser capaz de executar aplicativos originalmente escritos para DOS, OS/2, versões anteriores do Windows e aplicativos de acordo com o padrão POSIX 2. Assim, satisfazendo aos requisitos de poder executar aplicativos originalmente escritos para sistemas operacionais anteriores, o Windows NT teria um custo de adoção mais baixo, uma vez as empresas não precisariam renovar seu ecossistema de aplicativos para poder usá-lo. Já o requisito de aderência ao padrão POSIX se mostra necessário para eventuais contratos com cláusulas do tipo: “o sistema operacional a ser utilizado deve estar de acordo com o padrão POSIX”.
Os requisitos não-funcionais podem ainda ser divididos em três tipos: de produto, de processo e externos. Os requisitos não-funcionais de produto podem, à primeira vista, nos parecer os únicos que deveríamos estudar. Isso se dá por eles estarem diretamente relacionados à qualidade do software e serem definidos como os requisitos que especificam as características que o software deve possuir. No entanto, devemos lembrar que a arquitetura de software não influencia apenas a qualidade final do software, mas também influencia (e é influenciada pela) a forma com que ele é desenvolvido e até mesmo a organização em que ela está inserida.
- Definição 3: requisito não-funcional de produto
- Requisito que especifica as características que um sistema ou subsistema deve possuir.
Os requisitos não-funcionais de produto, como já dito anteriormente, são relacionados à qualidade do software e são alcançados pelo que chamamos de atributos de qualidade. Portanto, quando existem requisitos em que o software deve ter algum grau de confiabilidade, certo nível de eficiência, ou ser portável para diversos sistemas operacionais, estamos descrevendo quais atributos de qualidade que o software deve exibir. Todos requisitos presentes no Exemplo 2 podem ser classificados como sendo de produto. Ainda retornaremos a esse assunto neste capítulo, mas antes devemos mostrar os outros tipos de requisitos não funcionais.
Os requisitos não-funcionais de processo são definidos como as restrições ao processo de desenvolvimento.
- Definição 4: requisito não-funcional de processo
- Requisito que restringe o processo de desenvolvimento do software.
Esse tipo de requisito é encontrado em muitas situações, principalmente em grandes empresas ou organizações. Por exemplo, é comum que o desenvolvimento de sistemas de software para o Exército Americano tenham como requisito ter o processo de desenvolvimento de acordo com a Joint Technical Architecture 3
Por fim, há os requisitos não-funcionais externos. Esses, muitas vezes, podem se classificar tanto como de produto quanto de processo e são extraídos do ambiente em que o sistema é desenvolvido. Esse ambiente pode ser tanto a organização, com políticas que devem ser seguidas ou seu atual ecossistema de software com o qual ele deve interoperar, quanto a legislação vigente do país em que o sistema está operando.
- Definição 5: requisito não-funcional externo
- Requisito derivado do ambiente em que o sistema é desenvolvido, que pode ser tanto do produto quanto do processo.
Por fim, como exemplo de requisitos externos, podemos citar:
Exemplo 3
O sistema de recomendação de livros deve ler as informações do sistema de aluguel de livros de uma biblioteca, onde cada registro de livro está de acordo com o padrão Dublin Core. Um requisito não-funcional externo desse sistema de recomendação é:
- (RNF-01): O sistema deve guardar os dados dos livros recomendados em um modelo mapeável para o modelo de dados definido pelo padrão Dublin Core [16].
Note que o uso do Dublin Core só é realmente necessário porque a comunicação entre os dois sistemas é esperada e que um sistema já adota esse padrão.
Diferenças entre requisitos funcionais e não-funcionais
Apesar da classificação dos requisitos de software em requisitos funcionais e não-funcionais ser bem aceita, devemos observar que na prática essa divisão pode não ser tão clara. Isso ocorre devido ao nível de detalhes contido em sua descrição ou mesmo devido ao tipo de sistema desenvolvido.
Podemos ilustrar o caso em que o nível de detalhes faz a diferença com o seguinte exemplo:
Exemplo 4
Se considerarmos um requisito de segurança de confidencialidade (e normalmente considerado não-funcional):
- (RNF-01): O sistema deve possibilitar o envio de mensagens de modo que não possam ser lidas a não ser pelos destinatários.
Uma vez que não especifica nenhuma funcionalidade, esse pode ser considerado um requisito não-funcional. Por outro lado, poderíamos deixar essa evidente característica de requisito não-funcional um pouco mais turva se adicionarmos um pouco mais de detalhes a ele:
- (RF-01): O sistema deve permitir aos usuários que criptografem suas mensagens usando as chaves públicas dos destinatários.
Agora, esse requisito seria melhor classificado como funcional, uma vez que especifica uma função do sistema, apesar do atributo de qualidade exibido pelo software ao final do desenvolvimento será o mesmo: segurança, mais especificamente confidencialidade das mensagens enviadas.
Já quando mencionamos que o tipo do sistema pode influenciar em como classificamos um requisito, basta apenas lembrarmos dos sistemas de tempo-real. Neles, a corretude do comportamento do sistema não depende só do resultado lógico da função, mas também quando esse resultado é obtido. Portanto, uma resposta cedo ou tarde demais pode estar tão incorreta quanto uma resposta logicamente errada.
Exemplo 5
Em um sistema de informação, consideramos o requisito não-funcional:
- (RNF-01): A busca por nome deve retornar os resultados em no máximo 100 milissegundos.
Já em um sistema de controle de voo fly-by-wire, devemos considerar o requisito a seguir como funcional, uma vez que respostas que não respeitam o intervalo de tempo especificado são tão inúteis quanto a falta de resposta dos sensores (podem causar a queda do avião):
- (RF-01): Novas amostras de dados dos sensores da aeronave devem ser obtidas a cada 20 milissegundos.
Apesar disso, vale notar que ambos os requisitos presentes no Exemplo 5 ditam que tanto o sistema de informação quanto o sistema fly-by-wire devem exibir o atributo de qualidade desempenho, mesmo que em graus diferentes.
Conflitos entre requisitos
Como requisitos de software têm impacto em um ou mais atributos de qualidade, pode acontecer de impactarem em atributos relacionados a outros requisitos. Quando isso ocorre, o impacto pode resultar em reforço do atributo ou em conflito.
Podemos perceber que não surgem grandes problemas quando dois ou mais requisitos reforçam o mesmo atributo de qualidade. Afinal, caso isso ocorra, o design da solução que atenda a um dos requisitos afetará apenas positivamente o design da solução que atenda aos outros requisitos.
Apesar do caso de requisitos que se reforçam não ser muito comum, podemos ilustrá-lo com requisitos que afetam à segurança do software, mais precisamente autenticidade e confidencialidade:
Exemplo 6
Se temos um sistema de mensagens instantâneas com os seguintes requisitos:
- (RNF-01): O sistema deve prover meios de autenticar os seus usuários.
- (RNF-02): Uma mensagem enviada a um usuário não pode ser lida a não ser pelo destinatário.
Podemos observar que os requisitos RNF-01 e RNF-02 se relacionam, uma vez que afetam a alguns aspectos de segurança do sistema. Eles se reforçam visto que é possível encontrarmos uma solução para RNF-01 que facilite RNF-02 e vice-versa. A solução no caso é a utilização criptografia de chave pública: tanto ela pode ser usada para autenticação de usuários quanto pode ser usada para encriptação de mensagens.
Por outro lado, requisitos conflitantes são mais comuns e adicionam dificuldade durante o design das soluções. Isso ocorre porque a solução para um requisito conflitante afeta negativamente outro requisito. Assim, o design do software terá que considerar diversos trade-offs a fim satisfazer melhor aos requisitos mais importantes, já que atender a todos de forma ótima não é possível.
Se adicionamos alguns requisitos de usabilidade ao Exemplo 6, esses novos requisitos certamente afetarão negativamente à solução apresentada. Isso ocorre porque é comum que soluções de segurança afetem aos requisitos de usabilidade, visto que essas soluções adicionam conceitos não familiares aos usuários (por exemplo, chaves criptográficas) ou adicionam mais passos para que os usuários realizem suas tarefas (por exemplo, inserir login e senha).
Expressando requisitos não-funcionais
Grande parte do trabalho de um arquiteto consiste em projetar sistemas que devem satisfazer requisitos não-funcionais. No entanto, a Engenharia de Requisitos é limitada quanto a métodos de análise e derivação de requisitos não-funcionais. Essa limitação, muitas vezes, obriga ao arquiteto a trabalhar com requisitos que carecem de métricas e valores-alvo. Isso dificulta o processo de design, uma vez que desconhecer requisitos é o mesmo que desconhecer os objetivos do design. Por este motivo, recomenda-se aos arquitetos que sempre busquem por requisitos que possuam valores e métricas bem definidos e, desta maneira, conheçam e possam medir os objetivos e o sucesso de seu design.
Todavia, nem sempre é possível trabalhar com requisitos bem definidos, uma vez que encontramos alguns problemas ao expressá-los. Os principais motivos da dificuldade de expressar requisitos não-funcionais são os seguintes:
- Alguns requisitos simplesmente não são conhecidos em etapas iniciais do ciclo de desenvolvimento. Por exemplo, a tolerância a faltas ou o tempo de recuperação pode ser muito dependente da solução de design.
- Alguns requisitos, como alguns relacionados à usabilidade, são muito subjetivos, dificultando bastante a medição e o estabelecimento de valores-alvo.
- E, por fim, há os conflitos entre requisitos. Como já foi apresentado, requisitos podem influenciar atributos de qualidade comuns ou relacionados, até fazendo com que requisitos sejam contraditórios.
Mesmo sendo difícil lidar com os requisitos não-funcionais, é obrigação do arquiteto projetar o software de modo que, ao fim do desenvolvimento, este exiba os atributos de qualidade esperados pelos stakeholders.






