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

[Projeto] DeviceControls

Não sei se foi muito overengineering, mas eu conseguir arrumar uma forma de não ter que digitar a checagem se está ligado ou não, toda vez que criar uma nova classe de dispositivos.

(não utilizei interface nesse exercício)

Classe ToggleDevice

package com.vikinhd.Classes;

public abstract class ToggleDevice {
    protected boolean State;

    public ToggleDevice() {
        State = false;
    }

    protected boolean isSameState(boolean newState) {
        return (State == newState);
    }

    public void toggle(boolean newState) {
        if (isSameState(newState)) {
            System.out.println("Has same state.");
        } else {
            if (newState){
                on();
                State = true;
            } else{
                off();
                State = false;
            }
        }
    }

    protected abstract void on();
    protected abstract void off();
}

Classe Light

package com.vikinhd.Classes;

public class Light extends ToggleDevice{
    public Light() {
        super();
    }

    @Override
    public void on() {
        System.out.println("Turned lights on.");
    }

    @Override
    public void off() {
        System.out.println("Turned lights off.");
    }
}

Classe AirConditioner

package com.vikinhd.Classes;

public class AirConditioner extends ToggleDevice{
    public AirConditioner() {
        super();
    }

    @Override
    protected void on() {
        System.out.println("Turned air on.");
    }

    @Override
    protected void off() {
        System.out.println("Turned air off.");
    }
}
1 resposta
solução!

Oii, Estudante! Tudo bem?

Que legal a sua abordagem! Você acabou aplicando, intuitivamente, um padrão de projeto (Design Pattern) chamado Template Method.

Isso não é necessariamente "overengineering" (exagero), é uma demonstração de que você já está pensando em reutilização de código e escalabilidade. Em sistemas reais, evitar repetir a lógica de "verificar estado" (if (!ligado) ...) em cada nova classe é uma prática excelente.

Vou pontuar alguns detalhes para conectar sua solução com o objetivo do exercício:

  1. Por que o exercício pediu Interface?

O objetivo didático ali era focar no contrato.

  • Interface (Controlavel): Diz O QUE a classe deve fazer (ligar/desligar), mas não se importa com COMO ela faz. Isso permite que classes que não têm nada a ver uma com a outra (ex: um Carro e uma Luz) possam ser tratadas da mesma forma pelo sistema.
  • Sua solução (ToggleDevice): Define COMO o estado é gerenciado. Ela cria uma hierarquia forte (herança).
  1. O desafio da mensagem genérica

Um ponto de atenção na sua solução é a mensagem "Has same state". O exercício pedia mensagens personalizadas ("Luz já está ligada", "Ar já está ligado").
Como a lógica do System.out.println está na classe mãe (ToggleDevice), ela não sabe "quem" é a classe filha para personalizar o texto, a menos que você passe o nome do dispositivo para ela.

  1. O melhor dos dois mundos

Pra atender ao exercício (usar Interface) e manter sua lógica inteligente (Classe Abstrata), você poderia combinar as duas coisas!

A classe abstrata implementa a interface, e as classes concretas (Luz, Ar) herdam da abstrata.
A interface (O contrato):

public interface Controlavel {
    void ligar();
    void desligar();
}

A classe abstrata:

// ela implementa Controlavel, então é obrigada a ter ligar/desligar
public abstract class DispositivoEletronico implements Controlavel {
    protected boolean ligado = false;

    // método auxiliar para não repetir lógica (seu "engine")
    protected void alterarEstado(boolean novoEstado, String nomeDispositivo) {
        if (ligado == novoEstado) {
            String estadoStr = novoEstado ? "ligado(a)" : "desligado(a)";
            System.out.println(nomeDispositivo + " já está " + estadoStr + ".");
        } else {
            ligado = novoEstado;
            executarAcaoReal(); // chama o método abstrato específico
        }
    }

    // método abstrato para a ação específica do dispositivo (barulho, luz, etc)
    protected abstract void executarAcaoReal();
}

A classe concreta (A implementação):

public class Luz extends DispositivoEletronico {

    @Override
    public void ligar() {
        // Chama a lógica da mãe passando o estado desejado e o nome
        alterarEstado(true, "Luz");
    }

    @Override
    public void desligar() {
        alterarEstado(false, "Luz");
    }

    @Override
    protected void executarAcaoReal() {
        if (ligado) {
            System.out.println("Luz ligada.");
        } else {
            System.out.println("Luz desligada.");
        }
    }
}

A sua lógica tá certíssima pra evitar repetição de código (DRY - Don't Repeat Yourself). O único ajuste seria garantir que ela cumpra o contrato da Interface pedida no exercício e permita mensagens personalizadas.

Parabéns por ir além do básico!

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!