Your SlideShare is downloading. ×
Revisão de C# 4.0
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Revisão de C# 4.0

1,605
views

Published on

Estes são slides do treinamento que ministrei falando sobre orientação a objetos com o .NET e algumas boas práticas. O público-alvo são pessoas que programam há pelo menos 3 anos.

Estes são slides do treinamento que ministrei falando sobre orientação a objetos com o .NET e algumas boas práticas. O público-alvo são pessoas que programam há pelo menos 3 anos.

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,605
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Módulo 1: Revisão de C# e plataforma .NET Práticas modernas de desenvolvimento de software utilizando a plataforma .NET
  • 2. IntroduçãoEste curso busca mostrar como utilizar o C#e suas funcionalidades mais modernasatravés de exemplos práticos. Como opúblico alvo do treinamento é odesenvolvedor com pelo menos 3 anos deexperiência, o foco será em boas práticas e ouso do bom-senso nas decisões de projeto.
  • 3. Bibliografia recomendadaPara acompanhar este curso, recomenda-seter em mãos os seguintes livros.• C# in Depth – John Skeet, 2nd Ed, Manning• Accelerated C# 2010 – Trey Nash, Apress• C# 5.0 in a Nutshet – J. Albahari, 5nd Ed, O’Reilly• Pro C# 5.0 and .NET 4.5 – Andrew Troelsen, 6th Ed, Apress
  • 4. Vantagens da utilização do .NET• Ao dominar a plataforma .NET, o desenvolvedor tem a possibilidade de criar aplicações modernas que hoje em dia rodam na nuvem, no celular, no Windows e na Web.• O C#, em setembro de 2012, é a 5ª. linguagem de programação mais utilizada do mundo. Fonte: http://www.tiobe.com/index.php/content/pap erinfo/tpci/index.html
  • 5. Vantagens da utilização do .NET• Os principais tipos de aplicações .NET são: – Programação Web, com ASP.NET Web Forms e ASP.NET MVC – Programação Windows, com Windows Presentation Foundation (WPF) e Windows Forms. – Integração de Sistemas, com Windows Communication Foundation (WCF) e ASP.NET Web API
  • 6. Vantagens da utilização do .NET• Além dessas importantes aplicações, você pode trabalhar com .NET em: – Programação para Office – Customização de Sharepoint – CLR Stored Procedures do SQL Server – Windows Services – Silverlight – Windows Phone 7 – Windows 8 – Windows Azure
  • 7. Parte 1DESIGN BÁSICO DE CLASSES
  • 8. Design de Classes• O tipo mais comum no C# é a classe. Ela contém a maior parte da lógica de uma aplicação.• Uma classe é composta por vários tipos de membros, como métodos, propriedades/indexers, campos, eventos, delegates, enums.• Uma classe bem construída deve conter apenas uma única responsabilidade.• O construtor da classe deve explicitar suas dependências e validar, no próprio construtor, se os parâmetros passados são válidos ou não.
  • 9. Design de Classes• As referências recebidas pela classe devem ser guardadas sempre em campos readonly.• Evite ao máximo propriedades públicas que possam ser alteradas de fora da classe. Use, sempre que possível, propriedades somente- leitura. Tipos imutáveis são muito mais amigáveis para se utilizar e evitam bugs.• Siga rigorosamente o padrão de nomenclatura da plataforma .NET, definido em: http://msdn.microsoft.com/en- us/library/vstudio/ms229002(v=vs.100).aspx
  • 10. Design de Classes• Evite ao máximo, métodos longos. O limite ideal para um método é de 30 linhas. O método inteiro deve caber na tela.• Evite um quantidade grande de parâmetros. Se o número de parâmetros passar de 4 ou 5, crie uma classe para organizar os parâmetros. Uma vantagem desta metologia é que esta classe também pode ser utilizada para validar os argumentos da função principal.• Ao projetar um método, é interessante retornar um resultado para que seja possível realizar testes unitários ou pelo menos, conferir manualmente se o processamento ocorreu ok.• Escolha entre propriedade e método com sabedoria. Um método representa uma ação da classe. Uma propriedade representa estado da aplicação.
  • 11. Tipos Estáticos e não-estáticos• Na vasta maioria das vezes deve-se criar classes não estáticas. Uma classe estática em C# serve apenas para guardar métodos. Por esse motivo, ela acaba ferindo o conceito de orientação a objetos. Logo, uma classe estática deve, como sempre, possuir uma responsabilidade pequena e bem clara, servindo apenas de suporte ao projeto principal, que é uma aplicação orientada a objetos.• Exemplos no .NET: Math e Environment.
  • 12. Tipos Estáticos e não-estáticos• No dia-a-dia o padrão é se criar classes não estáticas e alguns métodos estáticos.• Métodos estáticos pertencem à classe e não ao objeto que é instanciado.• Diferentemente de classes estáticas, métodos estáticos são bem mais úteis e podem servir para colocar alguma lógica independente de instância no domínio da aplicação.
  • 13. Tipos Estáticos e não-estáticos• Na quase totalidade dos casos é uma péssima prática guardar estado na aplicação. Logo, guardar informações em propriedades ou campos estáticos é péssimo.• Evite singletons.• Evite propriedades estáticas read/write.• Não crie classes que dependam de classes ou propriedades estáticas.
  • 14. Tratamento de Erros• Ao construir uma classe, sempre lance uma exceção quando aplicável.• Ao executar um método, sempre lance uma exceção quando aplicável. Isso é válido também para tarefas como validação de tela.• Vale a pena criar uma exceção para carregar erros da aplicação, como erros em regras de negócio.• Ao lançar exceções, sempre coloque o máximo de informações possível. Isso ajuda a depurar e ajuda a melhorar a qualidade do log de erros a aplicação.
  • 15. Tratamento de Erros• Evite ao máximo usar o bloco catch para tratar erros. Só faz sentido tratar erros que realmente são previstos e óbvios de se tratar. Outros erros devem ser propagados.• Utilize sempre o bloco finally para fazer a limpeza de recursos após um erro.• Sempre utilize exceptions que já existam no .NET, como ArgumentNullException, InvalidOperationExcepti on, NotSupportedException e etc.• Sempre tente evitar o lançamento de uma exceção. O ideal é checar se uma operação poderá dar certo antes para evitar problemas de performance.
  • 16. Structs• Utilize o tipo struct para guardar informações simples e leves.• Não compensa utilizar a struct quando a instância ultrapassar 16 bytes.• Evite colocar lógica demais em uma struct – o principal propósito do seu uso é passar informações de forma leve e fácil.
  • 17. Tipos de valor e referência• No .NET a vasta maioria dos objetos são reference types. Os value types se restringem a alguns tipos básicos de dados como os numéricos, bool, Guid e structs.• Qualquer struct é um value type.• Qualquer class é um reference type.
  • 18. Tipos de valor e referência• O modo padrão de se passar parâmetros para os métodos é por referência, isto é, o método recebe, na prática, uma referência para o endereço de memória do objeto.• É possível passar reference types e value types tanto por valor como por referência.
  • 19. Tipos de valor e referência• Passar value type por valor: significa que você está passando uma cópia da variável para o método.• Passar value type por referência: significa que você está dando a posse da variável para o método, que poderá modificar a variável como quiser.
  • 20. Tipos de valor e referência• Passar reference type por valor: significa que você está passando um endereço com coisas que o método poderá modificar. Mas o método não pode modificar o endereço da referência em si.• Passar value type por referência: significa que o método tem controle total do reference type e também, do seu endereço da memória. Com o isso, ele pode até mesmo substituir o endereço recebido por outro endereço de memória com outros objetos completamente diferentes.
  • 21. Coleções e Arrays• O .NET oferece 2 tipos básicos de coleções: genéricas e não-genéricas.• Na prática, as coleções genéricas são mais úteis pois são fortemente tipadas.• Coleções genéricas suportam queries em LINQ. Esta vantagem torna o uso de coleções não-genéricas obsoleto.• Os tipos mais comuns de coleções são: List<T>, IEnumerable<T> e Dictionary<K,V>. A maioria das coleções do .NET herdam de IEnumerable e/ou IEnumerable<T>. O laço foreach consegue enumerar tudo o que for IEnumerable.
  • 22. Coleções e Arrays• Os Arrays ainda são utilizados e se comportam praticamente como coleções. A grande diferença é que as coleções são wrappers de arrays, destinadas a facilitar o uso de arrays.• Arrays possuem tamanho fixo. Coleções podem variar de tamanho• Geralmente se utiliza arrays para guardar coleções de tipos básicos, onde é necessário performance e rapidez. Exemplo: ler bytes de um arquivo.
  • 23. Enums• As Enums são value types que consistem em um conjunto de valores possíveis para a propriedade de um objeto. Elas tornam fortemente tipados o parâmetro/retorno de um método ou propriedade. A grande vantagem de utilizar uma enumeração é o aumento da legibilidade do código e tornar fortemente tipado, além de evitar bugs causados por lógica dependente de constantes.• Recomenda-se utilizar o Enum sempre que for possível. Esta prática torna o código mais extensível e permite que um valor seja atualizado no futuro sem grandes riscos.• Se não tiver certeza absoluta que um valor é booleano, utilize um Enum.• Se possível, defina um valor padrão para o caso zero.
  • 24. Exercício• Criar um sistema de controle de consultório médico. Tratar: – Pacientes – Médicos – Consulta – Agenda
  • 25. Parte 2ELEMENTOS AVANÇADOS DOC# 4.0
  • 26. Interfaces• As interfaces representam qualquer classe/struct que contenha um determinado conjunto de métodos, propriedades e eventos. Isto é, posso utilizar uma interface ao invés de uma classe concreta.• Um design orientado a objetos necessita de separação de responsabilidades. Uma das implicações é confiar no que é recebido como parâmetro e realizar seu trabalho.• Interfaces são contratos. Este importante tipo indica que, por contrato, o objeto que implementa a interface possui, no mínimo, os membros expostos na interface. Por exemplo, a classe que sabe dirigir consegue dirigir qualquer carro que tenha o volante, acelerador, freio, pedal de embreagem e câmbio. Pouco importa para a classe que vai utilizar o carro como tais recursos são implementados.
  • 27. Interfaces• O uso de interfaces é fundamental para se construir um software que seja fácil de evoluir e manter. A ausência de abstrações torna o código amarrado a uma implementação específica e torna muito arriscado e custoso mudar esta implementação para outra. Por exemplo, ao mudar de banco de dados, o código com alto grau de acoplamento sofrerá muito mais, a ponto de ser mais prático criar uma segunda versão “para Oracle” e mais tarde, assumir o risco de evoluir 2 ou 3 sistemas em paralelo.
  • 28. Interfaces• Evite criar contratos muito grandes.• Evite criar interfaces que fazem muita coisas• Crie interfaces com o mínimo possível de membros. Evite colocar na interface membros referentes a uma implementação específica. Nunca se esqueça que além de tudo, a interface precisa ser útil para o usuário final.• Embora algum nível de abstração seja importante, o excessivo número de abstrações torna o sistema muitas vezes mais difícil de entender e manter.• Sempre crie pelo menos uma implementação da sua interface, de preferência, útil para o usuário final.• Sempre que fizer sentido, declare o objeto utilizando a interface e não a implementação concreta.
  • 29. Interfaces Genéricas• Interfaces genéricas são muito úteis para criar contratos fortemente tipados que variem apenas com um parâmetro. Por exemplo, para não ter que definir uma interface IList<int>, IList<string>, define-se uma interface IList<T>.• Sempre que possível crie interfaces genéricas
  • 30. Delegates• Delegates estão para métodos assim como interfaces estão para classes.• Delegates são objetos que sabem como chamar um método. Funcionam como uma espécie de ponteiro para um método.• Delegates têm assinatura – isto é – eles só combinam com métodos que tenham os mesmos parâmetros e o mesmo tipo de retorno.
  • 31. Delegates• As principais utilidades do delegate são: – Passar um método como parâmetro de outro método. – Criação de eventos. – Programação assíncrona• O delegate pode ser visto como um objeto que guarda um link para qualquer lógica que possa ser executada mais tarde.• O desenvolvedor precisar criar o delegate e apontar o mesmo para um método, que pode ser estático ou de instância. Com este delegate configurado, é possível invocar livremente este objeto no momento que for necessário, de forma síncrona ou assíncrona. Por exemplo, no caso de eventos, o .NET invoca o delegate e chama o event handler aplicável, como por exemplo, o método OnClick de um botão.
  • 32. Métodos anônimos• Como o delegate serve para apontar para uma lógica, em C# tal lógica pode ser definida como um método comum ou um método anônimo.• O método anônimo é um forma de simplificar o uso de delegates, já passando ao instanciar o delegate, uma implementação inline, evitando a necessidade de criar um novo método.
  • 33. Delegates genéricos• Na maioria absoluta da vezes um delegate recebe alguns parâmetros e retorna algo / não possuir valor de retorno.• O C# oferece os delegates genércios Func<T> e Action<T>. Eles já criados para trabalhar com a vasta maioria de combinações possíveis de métodos que são comumente encontrados durante o desenvolvimento .NET
  • 34. Delegates genéricos• O delegate Action<T> representa qualquer método que recebe um parâmetro do tipo T e não retorna nada. Por exemplo: public void Salvar(Pessoa p) pode ser representado por um Action<Pessoa>.• Também há versões que suportam métodos até 16 parâmetros.
  • 35. Delegates genéricos• O delegate Func<T, TResult> representa qualquer método que recebe um parâmetro do tipo T e retorna um objeto do tipo TResult. Por exemplo: public int ObterIdade(Pessoa p) pode ser representado por um Funct<Pessoa,int>.• Também há versões que suportam métodos até 16 parâmetros.
  • 36. Delegates genéricos• Na prática, desde o C# 3.0 / NET 3.5 não é preciso criar mais seus próprios delegates. Em 99% dos casos basta encontrar um Func ou Action que sirva para a situação.• Com a tipagem implícita que o .NET 3.5 oferece, quase nunca é necessário declarar explicitamente qual delegate é necessário para combinar com o método.
  • 37. Lambda Expressions• A partir do C# 3.0 / .NET 3.5 é possível criar lógica de forma mais simples para ser utilizada como um delegate.• A sintaxe para métodos anônimos é confusa. O uso de lambda expressions ajuda muito a limpar esta sintaxe.• A lógica inline é um jeito totalmente novo de se passar código executável para um método que aceita um delegate como parâmetro. Por exemplo, um List<Pessoa> possui um método Find(Predicate<Pessoa> match). O delegate Predicate representa um método (seja ele normal, anônimo ou lambda) que representa uma condição. Logo, posso encontrar pessoas passando lógica como: var pessoa = pessoas.Find(p=>p.Peso > 80.0);• A lógica inline ajuda muito ao trabalhar com LINQ, pois permite, de forma simples, passar um closure que combine com um delegate de forma muito rápida, simples e fortemente tipada.
  • 38. Lambda Expressions• Esta forma de passar lógica para métodos aumenta brutalmente a produtividade do desenvolvedor e permite que o mesmo evite ter que criar métodos, delegates, métodos anônimos para criar uma lógica que só vai ser utilizada naquele contexto.• Na prática, hoje em dia só se cria lambda expressions. Os métodos anônimos caíram em desuso, assim como delegates customizados.• O lambda expression se traduz automaticamente em algum delegate que combine com o método que recebe o delegate. Logo, quase nunca é preciso sequer pensar em qual delegate será utilizado.
  • 39. LINQ• O LINQ é uma tecnologia que foi lançada no .NET 3.5 que revoluciona a forma com que se trabalha com dados em aplicações.• Com o uso de sintaxe e operadores inteligentes, é possível reduzir drasticamente a quantidade de código gerado pelo desenvolvedor.• O LINQ traz novas palavras-chave para o C# similares à linguagem SQL. Com isso, é possível fazer queries em dados de forma análoga ao que é possível fazer com SQL.
  • 40. LINQ• O LINQ faz o uso de delegates, lambda expressions e extension methods para dar suporte para criar uma grande variedade de consultas diretamente de dentro do código.• O LINQ é base para tecnologias como Entity Framework, LINQ to Objects, LINQ to SQL e LINQ to XML.
  • 41. Demo – LINQ to Objects
  • 42. Parte 3ORIENTAÇÃO AO OBJETOSMODERNA COM C#
  • 43. Princípios de OO• Um design orientado a objetos foca em três princípios básicos: 1. Encapsulamento 2. Herança 3. Polimorfismo
  • 44. Princípios de OO• É necessário entender que em C# e .NET algumas “coisas” são objetos e outras coisas são membros de um objeto.• Class, struct, enum, delegate podem ser considerados tipos, isto é, eles são objetos utilizáveis a partir do momento que existem.• Métodos, propriedades, campos e eventos são considerados membros de um objeto, pois eles não podem existir fora de um determinado objeto.• Em orientação a objetos, os elementos mais importantes são a classe e a struct. Os demais objetos são features do .NET para suportar diversos e igualmente importantes casos de uso.
  • 45. Princípios de OO• Todos os objetos em C# herdam de System.Object. Assim como em Java, todos tipos de valor e referência herdam são objetos• Tipos básicos como int, DateTime, string são classes ou structs. O compilador do C# e da maioria das linguagens oferece sintaxe mais amigável para se trabalhar com tipos básicos. Mas não se pode esquecer que mesmo os tipos básicos são objetos como outros quaisquer, suportando métodos estáticos e de instância normalmente.
  • 46. Princípios de OO - Encapsulamento• Encapsulamento significa proteger o objetos de alterações indesejáveis de outros objetos do sistema.• Os objetos guardam estado utilizando variáveis visíveis para toda a instância da classe. Os campos são variáveis que podem ser modificados livremente pelas classes.• Nunca crie um campo público. Utilize sempre propriedades para expor e modificar os campos da sua classe. Com isso, a classe que é dona do campo mantém total controle sobre alterações do valor do campo. Por exemplo, o campo _velocidadeAtual da classe Carro não pode ser modificável de fora da classe Carro. Se alguém quiser modificar a velocidade do carro, deverá chamar o método Acelerar() ou Frear(). Para expor a velocidade atual para o mundo, crie uma propriedade pública para isso.
  • 47. Princípios de OO - Encapsulamento• Encapsulamento também significa esconder do mundo detalhes de implementação de uma classe.• Não obrigue os usuários da sua API a “aprender” como utilizar um método. Esconda detalhes de implementação ao máximo e torne público o mínimo necessário de métodos para implementar a funcionalidade.• Utilize com sabedoria a visibilidade dos membros da sua classe. Torne privado o maior número possível de membros que modificam o estado o seu objeto.• A imutabilidade de uma classe é importante pois ajuda a criar sistemas onde vários componentes escrevem valores no mesmo lugar, obrigando os desenvolvedores a debugar e procurar quais valores foram alterados.• Ao expor coleções, torne o campo sempre readonly. A troca da instância de uma coleção pode causar bugs difíceis de resolver. É muito interessante expor listas para que os cliente da API consigam realizar queries em LINQ. Quando possível, exponha listas imutáveis utilizando ReadOnlyCollecton<T>.• Ao expor resultados de consultas com LINQ, tome cuidado para não enumerar múltiplas vezes o mesmo IEnumerable. Este efeito colateral
  • 48. Princípios de OO – Herança e Polimorfismo• Outro conceito importante da orientação a objetos é a possibilidade de criar novos objetos a partir de objetos já existentes.• Para enxergar a herança, é preciso pensar se existe uma relação “é-um”. Por exemplo, Carro : Automovel, pois o carro é um automóvel também. Ele estende o conceito básico de um automóvel.
  • 49. Princípios de OO – Herança e Polimorfismo• A herança é uma poderosa forma de construir novos objetos utilizando a funcionalidade já existente em outros objetos.• É possível alterar substituir a funcionalidade existente da classe mãe na classe filha• É possível impedir que uma classe seja herdada.• É possível impedir que as classes filhas alterem certos membros da classe mãe.
  • 50. Princípios de OO – Herança e Polimorfismo• Marque um método com a palavra-chave override para sobrescrever um método da classe base.• Para permitir que o seu método seja alterado por uma classe filha, marque-o com a palavra-chave virtual. Métodos virtuais significam que o comportamento da classe base já é útil para ser utilizada em produção – ela está pronta para ser estendida por classes filhas.• Marque uma classe como sealed para impedir que ela sofra herança. O .NET, ao encontrar uma classe sealed, interrompe a busca nos assemblies da aplicação, otimizando o tempo de carregamento da classe. Ou seja, vale a pena marcar classes que não têm a intenção de serem estendidas como sealed.
  • 51. Princípios de OO – Herança e Polimorfismo• Para ignorar a implementação de um método da classe base, sem sobrescrever o comportamento, utilize a palavra-chave new. Não é recomendável alterar completamente o método da classe base. Os clientes da sua API esperam que uma implementação da classe filha tenha um comportamento virtualmente igual ao da classe base, com alguma alteração ou outra. Se o método Carro.Acelerar() acelera o carro, uma classe filha não pode substituir o comportamento deste método e fazer com que o carro pare. E logicamente, é totalmente indesejável que o comportamento da classe filha mude o estado da classe mãe de forma inesperada.• Na prática, considere como públicos os métodos public e protected de sua classe. Isto é, qualquer membro que for passível de ser modificado por classes derivadas também correm os mesmos riscos de terem o encapsulamento quebrado. Vale a pena diminuir ao máximo a superfície de métodos visíveis de fora de sua classe.
  • 52. Princípios de OO – Classes Abstratas• Classes abstratas representam um conceito base que já contém alguma implementação base, mas que precisa necessariamente ser complementado por uma classe filha. Por exemplo, a classe Veículo não pode ser utilizada diretamente. Embora ela tenha rodas, motor e porta, precisa da classe Carro ou Moto para poder se falar em um objeto completo e pronto para uso.
  • 53. Princípios de OO – Classes Abstratas• Para que uma classe se torne abstrata, ela precisa ser marcada com a palavra-chave abstract. Ela pode definir um conjunto de métodos, com implementação mas para ser utilizada precisa ser estendida por uma classe concreta. Uma classe abstrata pode conter métodos abstratos. Tais métodos possuem somente assinatura e não podem conter um corpo. A classe concreta precisa necessariamente implementar este método.
  • 54. Classes Abstratas e Interfaces• Classes abstratas são parecidas com interfaces, pois ambas representam um conjunto de funcionalidades a se serem absorvidas pela classe concreta.• Utilize classes abstratas quando precisar de um comportamento padrão para uma família de classes.• Utilize interfaces quando basta apenas garantir que as qualquer classe que implemente a interface terá um conjunto de membros exatamente igual.• A vantagem do uso de interfaces é que não é necessário herdar e implementar todo um comportamento que pode ser complexo – basta expor o método que a interface exige.• O uso de classes abstrata se torna ainda mais poderoso com o uso de Generics, pois é possível utilizar uma mesma implementação base para qualquer parâmetro da classe. Por exemplo, uma classe base Fabrica<T> pode expor um método abstrato public abstract T Produzir, onde o tipo T pode representar qualquer tipo de produto. Com isso não é necessário fazer uma classe para cada tipo de fábrica onde só o produto produzido muda.
  • 55. Composição e Herança• Outra forma de estender comportamento de uma classe é utilizar outra classe como parte da classe original. Por exemplo, classe Funcionario pode ser aumentada com a criação de uma propriedade pública chamada PacoteBeneficios. Este é uma relação “possui-um”. Não faria sentido o pacote de benefícios “ser um” funcionário ou vice-versa.• Geralmente é preferível trabalhar com composição pois a família de objetos fica mais simples de entender.• Quanto maior o nível de herança, mais complexo e mais difícil se torna trabalhar com um objeto. Embora antigamente muitos desenvolvedores se orgulhassem de ter uma herança complexa de objetos, a grande verdade é que a maioria dos problemas do dia-a-dia são mais facilmente resolvidos por composição do que por herança. Não se obrigue a impor uma herança. Primeiro desenvolva pensando em classes concretas. Quanto encontrar classes que possuam funcionalidade em comum (por exemplo, cadastrar no banco de dados, ler dados de alguma entrada como disco/rede/web, aí sim faz sentido fazer um refactoring das classes para centralizar o código e montar uma herança.
  • 56. Composição e Herança• Ao utilizar outras classes para compor sua classe, tente, sempre que possível, não depender diretamente da classe concreta. Busque sempre depender de tipos menos derivados ou interfaces. Isso torna a sua implementação menos dependente de detalhes de implementação de outras classes, diminuindo o risco de ser afetada por mudanças em outras classes.• Busque sempre manter o mínimo possível de responsabilidades em uma mesma classe. Com este estilo de design, alterações em campos de tabela, regras de negócio, por exemplo, só afetariam um pequeno pedaço do sistema.
  • 57. Classes Genéricas• Uma classe genérica funciona como uma classe normal, porém, ela suporta uma parâmetros. Estes parâmetros permitem que se reutilizem uma mesma implementação para parâmetros diferentes.• Classes genéricas servem como templates, isto é, modelo de implementação que posteriormente são concretizadas ao se instanciar uma classe.
  • 58. Classes Genéricas• A classe List<T> em .NET é uma é genérica. Ela suporta o tipo T como parâmetro. Este tipo parametriza o List<T>, tornando-o concretamente um List<Pessoa>, List<string>, List<IEnumerab le<Pedido>>...• A utilização de classes genéricas, e tipos genéricos em geral economiza muito código. Não é preciso criar implementações específicas para cada nova situação.• É uma excelente prática criar e utilizar tipos genéricos, embora sua compreensão exija costume e prática.
  • 59. Extension Methods• Uma novidade no C# 3.0 / .NET 3.5 é a existência de extension methods. Este métodos basicamente disponibilizam novas funcionalidades para uma classe ou interface existente. Isto é, uma interface pode ter novos métodos para suportar cenários que não haviam sido previstos pelo desenvolvedor, ou que então, só fazem sentido em um contexto específico.
  • 60. Extension Methods• A utilização de extension methods ajuda a flexibilizar as regras da orientação a objetos. Ao colocar disponibilizar estes métodos em alguma biblioteca ou namespace, é possível resolver de forma simples situações que iriam requerer a criação de novas interfaces ou classes que herdem um comportamento já existente. Por exemplo, com extension methods é possível adicionar um método Count() à interface IRepository localmente, evitando a necessidade de criar uma nova interface que herde de IRepository só para guardar o novo método Count().• A flexibilidade dos extension methods permite um ganho de produtividade para o desenvolvedor, pois permite criar métodos úteis para estender classes comuns do .NET de forma simples e local (isto é, sem interferir em outros lugares do sistema).• Por exemplo, uma boa idéia é criar métodos que ajudem simplificar o tratamento de valores lidos de uma tela, como verificação de nulos, conversão de/para datas e etc.
  • 61. Extension Methods• O System.LINQ utiliza extension methods para aumentar a funcionalidade da Interface IEnumerable<T>. Com isso, ao referenciar esta biblioteca, você tem acesso a operadores LINQ.• Os operadores LINQ são métodos como Where, Select, All, Any, FirstOrDefault e muitos outros que são vistos em qualquer código C# após .NET 3.5.
  • 62. Extension Methods• Utilize com sabedoria esta funcionalidade. Não coloque métodos inesperados ou que causem efeitos colaterais inesperados na sua API. Por exemplo, não coloque um método Acelerar() na classe Volante!• Tenha bom sendo ao utilizar extension methods. Eles são úteis em muitos casos, mas é muito mais correto criar interfaces adequadas, classes abstratas aplicáveis e organizar o projeto de forma coesa e inteligível. O uso de extension methods, assim como métodos estáticos, ajudam a “driblar” os conceitos principais da orientação a objetos, como herança, polimorfismo e encapsulamento. Utilize extensions methos para aumentar a produtividade, otimizar trabalho repetitivo e adicionar localmente alguma lógica simples para simplificar o uso de um determinado objeto.
  • 63. Tipos anônimos• Uma funcionalidade interessante no C# 3.0 / .NET 3.5 é a criação de tipos anônimos. Com tipos anônimos, é possível criar objetos somente-leitura que sejam resultados de consultas em LINQ.• Estes objetos podem ser pensados como classes automáticas, que são feitas para transportar dados de um lugar para outro ou então, servem para juntar propriedades de diferentes objetos – uma composição.• É possível retornar objetos anônimos de métodos, desde que os mesmos sejam expostos como tipos dinâmicos. Tipos dinâmicos são imprevisíveis, isto é, não tem como saber a priori quais propriedades e métodos um objeto dinâmico terá. A passagem de tipos anônimos, a partir do C# 4.0, é muito facilitada com o uso do tipo dynamic.
  • 64. Dynamic• A partir do C# 4.0, o .NET introduziu a Dynamic Language Runtime – DLR, que é o suporte a tipos de dados dinâmicos no .NET. Com isso, o C# passa a suportar late binding além de early binding.• A tipagem dinâmica indica que o compilador não fará a checagem da tipagem das expressões no momento da compilação. Se você tentar chamar uma propriedade que não existe numa variável dinâmica, por exemplo, haverá um erro durante a execução do programa.• O C# introduziu a palavra-chave dynamic, o que faz com que todo o código que utilize esta variável também se torne dinâmico.
  • 65. Dynamic• É possível utilizar tipagem dinâmica em retorno de métodos, variáveis e até mesmo, em parâmetros de uma classe.• O ExpandoObject é um objeto especial que permite que se crie propriedades e métodos a um objeto em tempo de execução, tornando-o completamente dinâmico.• É necessário ter mais atenção ao lidar com tipos dinâmicos pois não há Intellisense ou qualquer ajuda do Visual Studio para tratar erros.
  • 66. Dynamic• O caso de uso comum é receber dados do banco de dados e passar para camadas acima – o usuário da sua camada de acesso a dados poderia usar tipagem dinâmica para ler os dados do banco como um IList<dynamic>.• O ASP.NET MVC utiliza modelos dinâmicos para que seja possível colocar qualquer tipo de informação para a View consumir.
  • 67. Próximos passos para estudo• SOLID – Princípios de design orientado a objetos que se usa muito no mercado• Design Patterns – alguns padrões clássicos de design de classes, que sempre se repetem