Geralmente quando se inicia a saga de um desenvolvedor, foca-se muito linguagens de programação, algoritmos, banco de dados enfim, tudo é muito novo. Queremos ver nosso código rodando, a tela funcionando e posteriormente, uma vez já agindo profissionalmente, ver o nosso cliente feliz. Cokm o passar do tempo nos deparamos com um tempo maior para dar manutenção, códigos que se repetem, concertos que causam erros, ou seja, começamos a ter pesadelos com um mau design de software. Hoje em dia, estudos afirmam que 80% do valor gasto com sofware é relacionado a manutenção de aplicações. Este indice negativo se deve ao fato de muitas vezes, os bons princípios de engenharia de software serem completamente ignorados. Quando isto acontece, os problemas citados anteriormente tiram o nosso sono e o perigoso “monstro monolítico” aparece. Veja a figura abaixo:
 
 

 
A arte de separar conceitos
    Quando uma cidade é construida, existe uma preocupação com o sistema de esgoto, água, luz, telefone e etc, e cada uma destas partes que compõem uma cidade existem a aqueles que se preocupam com cada uma destas partes. Em termos de arquitetura de sofware, não é diferente, e é justamente ai, que entra a separação de conceitos( Separation of Concerns – termo em inglês ).  Separar conceitos, é na verdade fazer com que uma aplicação seja modularizada, afim de focar resolver um único problema e caso precise realizar algo que não faz parte de sua tarefa, pede a outro módulo para colaborar quando se fizer necessário. A separação de conceitos, pode também ser aplicada a classes, métodos e componente sempre com o fim de que cada parte foque em resolver um único problema.
 
Separação de Conceitos e as camadas
   Uma das maneiras de se construir um sistema contemplando a separação de conceitos, é separar a sua aplicação em camadas e fazer com que cada uma delas foque em resolver tarefas apenas de sua responsabilidade.  As camadas, separam conceitos de acordo com a sua função dentro de uma arquitetura.  Observe a figura abaixo:
 

 
 
         É preciso entender, que não basta apenas separar em namespaces, isto é importante mais não é tudo. As camadas precisam interagir entre si, mais com todo cuidado de não invadir a privacidade ou responsabilidade da outra.  A ideia de separar conceitos, ou preocupações como queira, é ter um design simplificado, que seja apto a evoluir com facilidade e que também incentive o reuso de código, algo que muita das vezes não é muito explorado, mais dá ganho de produtividade e agilidade na hora de desenvolver.
 
Cadamas e o seu sentido
     Para que o artigo não fique muito abstrato, vamos abordar algumas camadas e o que seria a sua respectiva responsabilidade.
 
View: Esta camada é responsável por apresentar para o usuário a interface com a qual ele irá iteragir, ou seja, a única responsabilidade desta camada é a iteração com o usuário. É claro que esta camada, também será responsável, por coordenar todas as ações que o usuário poderá realizar nela e responder as iterações do mesmo como por exemplo habilitação de controles, redirecionamento, mensagens de notificação enfim.. a lógica da aplicação. Um exemplo desta camada, seriam as telas de um aplicativo windows forms ou por exemplo uma página web em uma aplicação MVC.
Application Layer: Esta camada, é a uma espécie de fachada que interage com a camada View.  A camda de aplicação, abstrai toda a iteração com a fonte de dados, sendo de sua responsabilidade obter requisições da view e passar para a camada de persistência que irá realizar alguma operação e retornar ou não um resultado. Esta camada, seria em um cenário MVC o controller, que é quem interage com a camada view obtendo requisições e realiza alguma ação na camada Model, de acordo com a requisição da view.
Domain Layer: Se você está familiarizado com o DDD( Domain Drive Design ), entende que esta camada é o coração do software de negócios. A camada de domínio, é quem armazena os objetos de negócios, e todos os relacionamentos entre estes objetos. Ao contrário do que foi feito por muito tempo, quando se utiliza o DDD como abordagem, o banco de dados é o último detalhe a ser observado. Passando a focar a modelagem nesta camada ou seja nas ideias, nos conceitos, na automatização do processo de negócios de acordo com as expectativas do usuário. Esta é a camada de maior responsabilidade e mais importante em um software de negócios.
DataBase Layer: A camada de banco de dados, ou poderia ser chamada de camada de fonte de dados, é responsável por realizar a persistência e armazenar as informações no banco de dados. Em um sistema moderno utiliza-se ORM´S( Object Relational Mapper ), para armazenar as informações no banco de dados. Utilizando um ORM, ganha-se produtividadeç. Quando estamos trabalhando com um modelo de objetos, faz-se necessário trabalhar com um ORM, pois somente fazendo uso dele, conseguimos evoluir nosso modelo de objetos sem causar um estrago no modelo de dados. Martin Faowler fala em seu livro de padrões de aruitetura, que ter uma camada de persistência permite evoluir tanto o modelo de objetoa, quanto o de dados em conjunto.
 
     É claro que as camadas abordadas neste artigo, são apenas um pequeno exemplo de como separar conceitos. É imprescindível, que você observe o cenário em que a aplicação irá rodar. Dependendo de qual for o cenário em questão, estas camadas podem sofrer alterações. Você talvez não vá utilizar alguma camada mostrada até aqui  ou além das camadas mostradas até aqui ainda precise utilizar outras. Mais independente de quantas ou quais camadas você for utilizar é importante ter clareza comunicação e dependências com um baixo acoplamento, para que as mudanças que por ventura possam ocorrer em seus software( que diga-se de passagem é uma quase que certeza ), não te dê pesadelos à noite.
     Bom pessoal, espero que eu possa ter ajudado em algo, esclarecendo ou tirando alguma dúvida. E colaborando de alguma forma para o crescimento profissional de quem acessa meus artigos abraços  e até mais.