VAGAS DE EMPREGO

balta.io balta.io
  • Cursos
  • Carreiras
  • Para sua Empresa
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog

Seja Premium
balta.io

  • Cursos
  • Carreiras
  • Para sua Empresa
  • Agenda
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog
  • Player
Seja Premium

Entre ou Cadastre-se

  • Home
  • Artigos
  • Orientação a objetos: Classes Seladas


👉 Temos uma versão mais atualizada deste artigo no nosso novo Blog

Orientação a objetos: Classes Seladas

Na orientação a objetos, uma classe selada não pode ser extendida e tomar esta decisão design pode ter diferentes impactos no consumo do seu código. Neste artigo vamos entender melhor quando utilizá-las.

Sobre o Flunt

Flunt é um pacote que criei para aplicar validações e o padrão Domain Notification. Com o tempo ele se tornou popular e tem até versões em Java/JS, o que é bem legal.

Modificador Sealed

No C# e em diversas outras linguagens orientadas à objetos nós temos um modificador chamado sealed que previne a classe de ser extendida.

Por tempos eu fiquei me perguntando onde eu usaria este modificador, qual seria um caso real para ele, e em 2017 acabei utilizando no Flunt.

Para tornar uma classe selada (Impedir que a mesma seja extendida), basta utilizar o seguinte exemplo.

public sealed class Notification 
{
    ...
}

Desta forma, se tentarmos criar uma nova classe que derive de Notification nos depararemos com o seguinte erro.

public class CustomNotification : Notification
{
    ...
}

ERRO

'Program.CustomNotification': cannot derive from sealed type 'Program.Notification'

Motivações

Tudo bem, você já entendeu o que é o sealed e como utilizar, mas agora vem a motivação para o seu uso.

Nas primeiras versões do Flunt eu não selei a classe Notification o que permitiu que outras classes fossem criadas sobre ela, e durante uma passagem por um dos meus clientes, notei que ele possuiam customizações destas notificações.

Não vou me recordar 100% agora, mas era algo como isto.

// Classe do Flunt
public class Notification 
{
    ...
}

// Derivações (No cliente)
public class ErrorNotification 
{
    ...
}

public class WarningNotification 
{
    ...
}

public class SuccessNotification 
{
    ...
}

Cada uma destas derivações tinha suas próprias customizações, seus métodos e suas propriedades. Como temos a possibilidade de upcast na OOP, estas classes também podiam substituir sua classe pai, a Notification.

Mas qual o problema nisso? Qual problema em criar customizações?

Algumas coisas não foram feitas para serem customizadas ou você não quer permitir que elas sejam feitas de formas diferentes.

A ideia por trás das notificações é ter uma padronização nas APIs por exemplo, onde todo erro 400 (BadRequest) retorna uma lista de notificações, algo parecido com isto.

{
    "status": 400,
    "message": "Falha na requisição",
    "data": null,
    "notifications": [
        { "Name": "Nome inválido" },
        { "Document": "CPF inválido" },
    ]
}

Desta forma, qualquer aplicação que consuma a API pode se preparar para o mesmo padrão, isto facilita a vida do Frontend que pode ter uma tipagem sobre o retorno de qualquer método da API, em suma, qualquer requisição a API resulta neste modelo.

Focando apenas no nó notifications, a classe Notification do Flunt deveria garantir que seu resultado fosse sempre neste padrão, ou seja, quem consome a API sempre pode esperar uma lista de notificações contendo chave/valor.

Porém, ao customizar (Extender) as notificações, o resultado podia variar de acordo com o tipo da notificação.

{
    "status": 400,
    "message": "Falha na requisição",
    "data": null,
    "notifications": [
        { "Name": "Nome inválido" },
        { "Document": "CPF inválido" },
    ]
}
{
    "status": 200,
    "message": "Cadastro realizado",
    "data": null,
    "notifications": [
        { "id": 1, "type": "success", "value":"Cadastro OK" }
    ]
}
{
    "status": 200,
    "message": "Cadastro realizado",
    "data": null,
    "notifications": [
        { "type": "success", "key":"XYZ", "value":"XPTO" }
    ]
}

Isto geraria no mínimo um switch no Frontend para saber o tipo de notificação e então tratá-la de forma diferente. Ainda vale lembrar que o Frontend não está limitado a Web, tem Flutter, Xamarin e várias outras tecnologias/linguagens.

Deste primeiro cenário veio a motivação para selar a classe Notification e padronizar todas as notificações dos sistemas que usam o Flunt.

Outro exemplo

Como comentei no começo deste artigo, esta foi uma decisão que tomei em 2017, mas o que me motivou a escrever este artigo foi outro cenário que passei hoje.

Em alguns pontos críticos de leitura das Apps/Apis do balta eu utilizo o Dapper para acesso à dados, inclusive tem um curso sobre isto aqui.

Porém, o Dapper é um micro-orm que extende o IDbConnection apenas, o que significa que estamos literalmente por conta própria para tudo, inclusive para gerenciar a conexão com o banco de dados.

Desta forma, eu sempre crio um classe para gerenciar a conexão e garantir que não vou deixar conexão aberta no meu SQL Server.

Fazer isto não é uma tarefa difícil, basta implementar a interface IDisposable e chamar o método Connection.Dispose para encerrar a conexão.

public sealed class DbSession : IDisposable
{
    private Guid _id;
    public IDbConnection Connection { get; }
    public IDbTransaction Transaction { get; set; }

    public DbSession()
    {
        _id = Guid.NewGuid();
        Connection = new SqlConnection(Settings.ConnectionString);
        Connection.Open();
    }

    public void Dispose() => Connection?.Dispose();
}

Mas e aí, você notou algo de diferente nesta classe? Sim, ela está selada e você já deve imaginar o motivo!

Pois é, se tem uma classe que não quero que alguém extenda é esta, ela é uma das mais importantes e sensíveis da aplicação, e sem o sealed nela, poderiam ter várias versões da mesma.

Ainda pior, com a possibilidade de upcast poderiamos facilmente substituir a conexão padrão por uma customizada que talvez esquecesse de fechar a conexão com o banco de dados.

Imagina o problemão que não arrumaríamos?

Conclusão

As vezes, na correria do dia-a-dia tendemos a fazer o mais fácil, e em diversos cenários, optaríamos por criar uma nova versão de uma classe do que dar manutenção e melhorá-la.

O modificador sealed age neste ponto, ele te ajuda a travar as classes que você não quer que sejam extendidas e forçar as coisas a seguirem um padrão.

Mas calma, não é para sair selando todas as classes do sistema só porque aprendeu algo novo hoje!

Populares

Priority Queue

Priority Queue ou fila prioritária é um tipo de lista inclusa no C# 10 que permite que seus itens...


Implicit Operators no C#

Implicit Operators permitem adicionar comportamentos de conversão a objetos Built In ou complexos...


ASP.NET 5 – Autenticação e Autorização com Bearer e JWT

Este artigo atualmente utiliza a versão 5.0.0-rc.1 do ASP.NET/.NET, o que significa que ainda não...


Clean Code - Guia e Exemplos

Saiba como manter seu código limpo (Clean Code) seguindo algumas práticas sugeridas pelo Robert C...


Git e GitHub - Instalação, Configuração e Primeiros Passos

Git é um sistema de controle de versões distribuídas, enquanto GitHub é uma plataforma que tem o ...


Compartilhe este artigo



Conheça o autor

André Baltieri

André Baltieri

Microsoft MVP

Me dedico ao desenvolvimento de software desde 2003, sendo minha maior especialidade o Desenvolvimento Web. Durante esta jornada pude trabalhar presencialmente aqui no Brasil e Estados Unidos, atender remotamente times da ?ndia, Inglaterra e Holanda, receber 8x Microsoft MVP e realizar diversas consultorias em empresas e projetos de todos os tamanhos.





3.133

Aulas disponíveis

292

horas de conteúdo

76.401

Alunos matriculados

52.960

Certificados emitidos





Comece de graça agora mesmo!

Temos mais de 21 cursos totalmente de graça e todos com certificado de conclusão.

Começar


Prefere algo mais Premium?

Conheça nossos planos



Premium anual

Compra única, parcelada em até
12x no cartão de crédito


12x R$

99

,79

=R$ 1.197,44
  • 1 ano de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 67 cursos disponíveis
  • 10 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade



Precisa de ajuda?

Dúvidas frequentes



  • Posso começar de graça?

    Sim! Basta criar sua conta gratuita no balta.io e começar seus estudos. Nós contamos com diversos cursos TOTALMENTE gratuitos e com certificado de conclusão.

  • Vou ter que pagar algo?

    Nós temos cursos gratuitos e pagos, porém você não precisa informar nenhum dado de pagamento para começar seus estudos gratuitamente conosco. Os cursos gratuitos são completos e com certificado de conclusão, você não paga nada por eles.

    Porém, caso queira algo mais Premium , você terá acesso à diversos benefícios que vão te ajudar ainda mais em sua carreira.

  • Por onde devo começar?

    Siga SEMPRE as nossas Carreiras , elas vão te orientar em todos os sentidos. Os cursos já estão organizados em categorias e carreiras para facilitar seu aprendizado.
    Nossa sugestão para aprendizado é começar pelo Backend e seguindo para Frontend e Mobile.

    • Backend
    • Frontend
    • Mobile

  • Os cursos ensinam tudo que preciso?

    Nenhum curso no mundo vai te ensinar tudo, desculpa ser sincero! Os cursos são uma base, eles fornecem por volta de 30% do que você precisa aprender, o resto é com você, com dedicação e MUITA prática.

  • O que eu devo estudar?

    Java ou .NET? Angular ou React? Xamarin ou Flutter? A resposta é simples e direta: "Você já sabe o básico?"

    Se você ainda não sabe BEM o básico, ou seja, os fundamentos, OOP, SOLID, Clean Code, está perdendo tempo estudando Frameworks ou até coisas mais avançadas como Docker. Foque nos seus objetivos primeiro.
    Agora se você está indeciso sobre qual Framework estudar, a boa notícia é que o mercado neste momento está bem aquecido e você tem várias oportunidade. Desta forma o que levaríamos em conta para tomar esta decisão seria:

    • Já sei o básico
    • O Framework/Tecnologia tem mercado onde eu estou (região)
    • O Framework/Tecnologia é utilizado em uma empresa onde quero atual
    • O Framework/Tecnologia resolve meu problema
    • Eu gosto de utilizar o Framework/Tecnologia

  • Estou pronto para estudar no balta.io?

    Com certeza! O primeiro passo é começar e você pode fazer isto agora mesmo!

    Começar de graça

Ainda tem dúvidas?





Assine nosso Newsletter

Receba em primeira mão todas as nossas novidades.

Cadastrar


balta.io

Sobre

  • Como funciona?
  • Seja Premium
  • Agenda
  • Blog
  • Todos os cursos

Cursos

  • Frontend
  • Backend
  • Mobile
  • Fullstack

Suporte

  • Termos de uso
  • Privacidade
  • Cancelamento
  • Central de ajuda

Redes Sociais

  • Telegram
  • Facebook
  • Instagram
  • YouTube
  • Twitch
  • LinkedIn
  • Discord