Olá José!
Como prometido segue uma analise mais detalhada sobre o seu código:
A estrutura geral está coerente para um exercício introdutório, mas há vários pontos que podem ser melhorados em termos de encapsulamento, segurança, coesão e robustez.
Segue a analise de cada classe:
- Classe
Conta
Problemas encontrados:
A senha não deveria ser armazenada como número inteiro.
Problemas: remove zeros à esquerda; limita caracteres; não representa corretamente o conceito de senha; facilita exposição indevida.
Saldo possui set público e isso quebra totalmente o encapsulamento.
Hoje qualquer código pode fazer: conta.Saldo = -999999; Isso é um bug lógico grave.
Nenhuma propriedade possui validação: titular pode ser vazio; número da conta pode ser negativo; saldo pode ser negativo.
A classe representa apenas dados, mas uma conta bancária deveria possuir comportamentos: sacar; depositar; transferir; validar senha.
Sugestão correta:
class Conta
{
public int NumeroConta { get; private set; }
private string _titular;
public string Titular
{
get => _titular;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Titular inválido");
_titular = value;
}
}
private string _senha;
public decimal Saldo { get; private set; }
public Conta(int numeroConta, string titular, string senha)
{
NumeroConta = numeroConta;
Titular = titular;
_senha = senha;
Saldo = 0;
}
public void Depositar(decimal valor)
{
if (valor <= 0)
throw new ArgumentException("Valor inválido");
Saldo += valor;
}
public bool Sacar(decimal valor)
{
if (valor <= 0 || valor > Saldo)
return false;
Saldo -= valor;
return true;
}
public bool ValidarSenha(string senha)
{
return _senha == senha;
}
}
- Classe
Carro
Essa foi a melhor implementação entre as três.
Você já utilizou: encapsulamento; validação em propriedade; expression-bodied members; propriedade calculada.
Boa aplicação de OOP.
Problemas encontrados:
Ano fixo em 2023. Esse é um bug de manutenção. Em 2026 o código já está desatualizado.
Correção:
value >= 1960 && value <= DateTime.Now.Year
Falta validação em Fabricante e Modelo
Hoje é possível:
carro.Modelo = "";
Sugestão correta:
private string _fabricante;
public string Fabricante
{
get => _fabricante;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Fabricante inválido");
_fabricante = value;
}
}
Mesmo conceito para Modelo.
Sua Classe está sem construtor.
O objeto pode nascer inconsistente:
var carro = new Carro();
Melhor abordagem:
public Carro(string fabricante, string modelo, int ano)
{
Fabricante = fabricante;
Modelo = modelo;
Ano = ano;
}
- Classe
Produto
Está possui problemas graves.
Campos públicos:
public string nome;
public string marca;
Isso viola encapsulamento.
Qualquer código pode alterar diretamente:
produto.nome = null;
O ideal é usar propriedades.
Mistura de português e convenção incorreta
Em C#: propriedades=PascalCase; campos privados= camelCase com _.
Hoje:nome, marca, preco fogem do padrão.
Uso de Console.WriteLine dentro da entidade.
Esse é um problema arquitetural importante.
A classe de domínio não deve controlar interface/saída.
Isso acopla a entidade ao console.
Métodos ObterPreco() e AtribuirPreco() mais parece Java antigo.
Em C#, propriedades resolvem isso de forma mais elegante.
Estoque não permite zero:
if (quantidade > 0)
Isso impede estoque zerado.
Mas estoque 0 é válido.
Bug lógico.
Refatoração recomendada
class Produto
{
public string Nome { get; set; }
public string Marca { get; set; }
private decimal _preco;
public decimal Preco
{
get => _preco;
set
{
if (value < 0)
throw new ArgumentException("Preço inválido");
_preco = value;
}
}
private int _estoque;
public int Estoque
{
get => _estoque;
set
{
if (value < 0)
throw new ArgumentException("Quantidade inválida");
_estoque = value;
}
}
public string DescricaoProduto =>
$"Nome: {Nome}" +
$"\nMarca: {Marca}" +
$"\nPreço: R$ {Preco:F2}" +
$"\nQuantidade em estoque: {Estoque}";
}
....tem mais...