Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Dúvida] Propriedade level pode ser novamente modificada fora da classe

Olá.

Ao definir um setter para level, voltamos ao problema de essa propriedade poder ser modificada diretamente fora da classe, ou seja, eu poderia fazer meuMago.level = 8 sem a necessidade do método aumentarLevel().

Por favor, existe uma maneira de criar um setter privado?

O que eu fiz para tentar contornar isso foi criar um método privado que modificasse o level e fizesse a mesma lógica que estava no setter. Aí modifiquei os métodos aumentarLevel() e diminuirLevel() para que chamassem esse método privado:

// método privado para substituir o setter de level
#setLevel(novoLevel) {
    if(novoLevel >= 1 && novoLevel <= 10) {
        this.#level = novoLevel;
    }
}

aumentarLevel() { 
    this.#setLevel(this.level+1);
}

diminuirLevel() {
    this.#setLevel(this.#level-1);
}

Com isso, não consigo modificar diretamente o level fora da classe, devendo obrigatoriamente utilizar somente os métodos que estão disponíveis (aumentarLevel() ediminuirLevel()).

Poderia ser dessa forma? Há outra forma mais recomendada?

Obrigado.

1 resposta
solução!

Olá Matheus, tudo bem?

Primeiramente, peço desculpas pela demora em responder!

De fato, como conversamos no curso, ao utilizar o setter, nós protegemos uma ação apenas dentro da lógica de negócio, podendo atribuir valor se ele estiver dentro da regra e isso é o esperado.

E parabéns pelo questionamento! Significa que você realmente entendeu a importância do encapsulamento.

Entretanto, da forma que foi feita o set perde completamente a sua utilidade, visto que você alocou a responsabilidade para outro método.

Você até pode proteger o set, mas a linguagem não permite fazer isso sem que haja um get protegido também. Modificando, o código completo da classe ficará assim:

export class Personagem {
    nome
    vida = 100
    mana = 100
    #levelPersonagem
    tipo
    descricao

    constructor(nome) {
        this.nome = nome
        this.#levelPersonagem = 1
    }

    aumentarLevel() {
        this.#level += 1
    }

    diminuirLevel() {
        this.#level -= 1
    }

    get level() {
        return this.#levelPersonagem
    }

    get #level() {
        return this.#levelPersonagem
    }

    set #level(novoLevel) {
        if (novoLevel >= 1 && novoLevel <= 10) {
            this.#levelPersonagem = novoLevel
        }
    }

    obterInsignia() {
        if (this.#levelPersonagem >= 5) {
            return `Implacavel ${this.constructor.tipo}`
        }
        return `${this.constructor.tipo} iniciante`
    }

    static verificarVencedor(personagem1, personagem2) {
        if (personagem1.level === personagem2.level) {
            return 'Empate!!!'
        }

        if (personagem1.level > personagem2.level) {
            return `${ personagem1.constructor.tipo } ${personagem1.nome} é o vencedor!`
        }

        return `${ personagem2.constructor.tipo } ${personagem2.nome} é o vencedor!`
    }

}

OBS: Eu tive que modificar o nome de level para levelPersonagem, para não conflitar com os nomes novos de getters e setters.

Dessa forma, se eu fizer magoAntonio.level = 8, não funcionará!

Essa pode ser uma solução! O único ponto é que dessa forma nós protegemos um get sem necessidade, apenas para que não quebre o código devido a exigência da linguagem. Em um contexto de mundo real, você também pode ver esse problema sendo solucionado com o TypeScript, como não é o foco do curso, foi por isso que não abordamos essa parte.

Espero ter ajudado, em caso de dúvidas ou dificuldades, estamos a disposição!

Abraços e bons estudos :)