Aprenda a Gerenciar Bibliotecas com OOP em C# Puro

Imagine ter uma biblioteca onde diversos livros são emprestados e devolvidos constantemente. Seria complicado ficar controlando tudo manualmente, certo? A solução é criar📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. um Sistema de Gerenciamento de Biblioteca usando Orientação a Objetos (OOP)! Neste projeto, você vai transformar conceitos abstratos em código funcional enquanto🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! descobre como:

Vamos construir juntos um sistema completo sem frameworks ou bibliotecas externas - puro C# e OOP! O foco será mostrar a lógica e a organização do código em C# usando OOP, reforçando princípios como criação de classes, encapsulamento🔒 Encapsulamento: Proteja Seus Dados como um Banco Suíço!🔒 Encapsulamento: Proteja Seus Dados como um Banco Suíço!Aprenda a proteger seus dados com encapsulamento em C#: técnicas e melhores práticas para um código seguro, modular e eficiente. de dados e comunicação entre objetos.

Público-alvo: Universitários, career switchers, devs de outras linguagens e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. até Product Managers que querem "falar a língua" dos devs!

📚 Tabela de Conteúdo🔗

1. Visão Geral do Projeto🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes.

2. Estrutura Básica de Classes🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara.

3. Criando e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Gerenciando Livros

4. Cadastrando Usuários

5. Realizando Empréstimos e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Devoluções

6. Organizando Tudo na Classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. Principal

7. Desafios Comuns & Soluções

8. Conclusão e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Próximos Passos

Visão Geral do Projeto🔗

Nosso sistema gerencia:

Exemplo de fluxo:

var livro = new Livro("1984", "George Orwell", "978-0451524935");
var usuario = new Usuario("Ana Silva", "[email protected]");
biblioteca.EmprestarLivro(livro, usuario);

Estrutura Básica de Classes🔗

Para começar, vamos definir algumas classes🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. essenciais. Pense em quais entidades compõem uma biblioteca:

Podemos adotar o seguinte diagrama mental simples (sem muitos detalhes de UML, apenas para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! ilustrar a ideia):

  • Book
  • User
  • LibraryManager

A classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. Book representará cada livro (seu título, autor, status de empréstimo etc.). Já a classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. User trará as informações de usuários (nome, identidade, número de empréstimos em aberto etc.). E📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. LibraryManager será responsável por controlar a listagem de livros e usuários, bem como emissões e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. devoluções.

Criando e Gerenciando Livros🔗

Vamos criar a classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. Book. Ela precisa, no mínimo🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!Aprenda a usar coleções e LINQ em C# para analisar vendas, filtrar dados e extrair insights estratégicos que otimizem decisões e impulsionem seu negócio., de um título, autor e um identificador único (por exemplo, o ISBN). Além disso, é interessante ter um campo que indique se esse livro está ou não emprestado.

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
    public string Isbn { get; set; }
    public bool IsBorrowed { get; private set; }
    public Book(string title, string author, string isbn)
    {
        Title = title;
        Author = author;
        Isbn = isbn;
        IsBorrowed = false;
    }
    public void BorrowBook()
    {
        if (IsBorrowed)
        {
            Console.WriteLine($"O livro '{Title}' já está emprestado.");
        }
        else
        {
            IsBorrowed = true;
            Console.WriteLine($"O livro '{Title}' foi emprestado com sucesso!");
        }
    }
    public void ReturnBook()
    {
        if (IsBorrowed)
        {
            IsBorrowed = false;
            Console.WriteLine($"O livro '{Title}' foi devolvido.");
        }
        else
        {
            Console.WriteLine($"O livro '{Title}' não está emprestado.");
        }
    }
}

Nesta implementação:

Cadastrando Usuários🔗

Precisamos de uma classe que represente quem vai pegar livros emprestados. Vamos criar a classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. User:

public class User
{
    public string Name { get; set; }
    public string DocumentId { get; set; } // Pode representar CPF ou matrícula, por exemplo
    public List<Book> BorrowedBooks { get; private set; }
    public User(string name, string documentId)
    {
        Name = name;
        DocumentId = documentId;
        BorrowedBooks = new List<Book>();
    }
    public void AddBook(Book book)
    {
        BorrowedBooks.Add(book);
    }
    public void RemoveBook(Book book)
    {
        BorrowedBooks.Remove(book);
    }
}

Nesta classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara.:

Realizando Empréstimos e Devoluções🔗

Aqui entra o gestor do nosso sistema: uma classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. que concentra as operações de busca e cadastro de usuários/livros. Vamos chamar de LibraryManager.

public class LibraryManager
{
    private List<Book> Books;
    private List<User> Users;
    public LibraryManager()
    {
        Books = new List<Book>();
        Users = new List<User>();
    }
    public void AddBook(Book book)
    {
        Books.Add(book);
    }
    public void AddUser(User user)
    {
        Users.Add(user);
    }
    public Book FindBookByIsbn(string isbn)
    {
        return Books.FirstOrDefault(b => b.Isbn == isbn);
    }
    public User FindUserByDocument(string docId)
    {
        return Users.FirstOrDefault(u => u.DocumentId == docId);
    }
    public void BorrowBook(string isbn, string userDocId)
    {
        var book = FindBookByIsbn(isbn);
        var user = FindUserByDocument(userDocId);
        if (book == null)
        {
            Console.WriteLine("Livro não encontrado.");
            return;
        }
        if (user == null)
        {
            Console.WriteLine("Usuário não encontrado.");
            return;
        }
        if (!book.IsBorrowed)
        {
            book.BorrowBook();
            user.AddBook(book);
        }
        else
        {
            Console.WriteLine($"O livro '{book.Title}' já está emprestado.");
        }
    }
    public void ReturnBook(string isbn, string userDocId)
    {
        var book = FindBookByIsbn(isbn);
        var user = FindUserByDocument(userDocId);
        if (book == null)
        {
            Console.WriteLine("Livro não encontrado.");
            return;
        }
        if (user == null)
        {
            Console.WriteLine("Usuário não encontrado.");
            return;
        }
        if (book.IsBorrowed)
        {
            book.ReturnBook();
            user.RemoveBook(book);
        }
        else
        {
            Console.WriteLine($"O livro '{book.Title}' não está emprestado.");
        }
    }
    public void ListAllBooks()
    {
        Console.WriteLine("=== Lista de Livros ===");
        foreach (var book in Books)
        {
            string status = book.IsBorrowed ? "Emprestado" : "Disponível";
            Console.WriteLine($"Título: {book.Title}, ISBN: {book.Isbn}, Status: {status}");
        }
    }
    public void ListAllUsers()
    {
        Console.WriteLine("=== Lista de Usuários ===");
        foreach (var user in Users)
        {
            Console.WriteLine($"Nome: {user.Name}, Documento: {user.DocumentId}");
        }
    }
}

O que acontece aqui:

Organizando Tudo na Classe Principal🔗

Para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! que tudo isso funcione, precisamos de um ponto de entrada na aplicação. Em um programa de console, seria o Main dentro de uma classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. como Program.

class Program
{
    static void Main(string[] args)
    {
        LibraryManager manager = new LibraryManager();
        // Adicionando alguns livros e usuários para teste
        manager.AddBook(new Book("Use a Cabeça! C#", "Andrew Stellman e Jennifer Greene", "12345"));
        manager.AddBook(new Book("O Programador Apaixonado", "Chad Fowler", "67890"));
        manager.AddUser(new User("Alice", "DOC001"));
        manager.AddUser(new User("Bob", "DOC002"));
        // Exibindo listas
        manager.ListAllBooks();
        manager.ListAllUsers();
        // Emprestando
        manager.BorrowBook("12345", "DOC001");
        manager.BorrowBook("67890", "DOC001");
        // Tentando emprestar de novo o mesmo livro
        manager.BorrowBook("12345", "DOC002");
        // Devolvendo um livro
        manager.ReturnBook("12345", "DOC001");
        // Exibindo lista final de livros
        manager.ListAllBooks();
    }
}

Esse código demonstra como podemos testar rapidamente as funcionalidades do nosso sistema em um ambiente de console. Claro, em um cenário real, você poderia ter o input do usuário em loop, perguntando qual operação deseja realizar, mas a estrutura de classes já está pronta para quase qualquer tipo de interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas..

Desafios Comuns & Soluções🔗

⚠️ Problema 1: Livro emprestado duas vezes

Solução: Estado no objeto Livro.

public class LivroFisico : Livro {
    public bool Disponivel { get; private set; } = true;
    public override void Emprestar(Usuario usuario) {
        if (!Disponivel) throw new InvalidOperationException("Livro indisponível");
        Disponivel = false;
        usuario.AdicionarLivro(this);
    }
}

⚠️ Problema 2: Acoplamento forte entre classes

Solução: Injeção de Dependência🎮 Projeto: Sistema de Notificações com Observer e DI!🎮 Projeto: Sistema de Notificações com Observer e DI!Descubra como sincronizar notificações em um sistema de delivery com o padrão Observer e Dependency Injection em C#. Obtenha código limpo, modular e escalável. manual.

public class Biblioteca {
    private INotificacao _notificador;
    public Biblioteca(INotificacao notificador) {
        _notificador = notificador;
    }
    public void NotificarAtrasos() {
        _notificador.Enviar("Seu livro está atrasado!");
    }
}

Conclusão e Próximos Passos🔗

Você montou a fundação de um sistema de gerenciamento de biblioteca com OOP puro em C#. As classes🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. Book, User e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. LibraryManager ilustram como organizar o código de forma que as responsabilidades estejam bem definidas (cada classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. cuidando do seu próprio papel). A partir daqui, você pode:

Próximos Passos:

1. Persistência de Dados: Adicione serialização⚡ System.Text.Json 2.0: Serialização com Source Generators!⚡ System.Text.Json 2.0: Serialização com Source Generators!Descubra como os Source Generators do .NET 8 revolucionam a serialização JSON, proporcionando performance 5x mais rápida e menor uso de memória. para salvar em JSON.

2. Interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. Gráfica: Migre para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! Windows Forms ou WPF.

3. Regras de Negócio: Implemente sistema de multas por atraso.

4. Testes Unitários🧪 Testes de Unidade para Tratamento de Erros: Previna Falhas Futuras!🧪 Testes de Unidade para Tratamento de Erros: Previna Falhas Futuras!Descubra como implementar testes de unidade focados em tratamento de erros, evitando surpresas em produção e garantindo sistemas confiáveis e robustos.: Garanta que novos recursos📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. não quebrem funcionalidades existentes.

Dica Profissional: Comece pequeno! Implemente uma funcionalidade por vez e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. valide cada passo com testes manuais.

🔥 Desafio Bônus: Adicione suporte para reservas de livros ainda não disponíveis!
public class Reserva {
    public Usuario Usuario { get; }
    public Livro Livro { get; }
    public DateTime DataReserva { get; }
    public Reserva(Usuario usuario, Livro livro) {
        // Implemente a lógica de prioridade!
    }
}

O mais importante é perceber como a lógica de Orientação a Objetos deixa tudo mais estruturado, facilitando a manutenção do projeto🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. e a expansão de funcionalidades.

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo

Artigos Relacionados