Skip to content

Latest commit

 

History

History
154 lines (117 loc) · 3.32 KB

solution.md

File metadata and controls

154 lines (117 loc) · 3.32 KB

SOLID Kata

SRP

  • Extract Printer logic in a dedicated class
  • Use IntelliJ to demonstrate the power
    • final fields in ccountService
  • Use lombok to remove useless code

OCP

  • Create Employee inheritance
  • Use private field

BONUS : add a new type of employee -> BigBoss

What do you have to do ?

LSP

  • Code smell : instanceof check
public void refuel(Vehicle vehicle) {
    if (vehicle instanceof PetrolCar) {
        vehicle.fillUpWithFuel();
    }
}

public void charge(Vehicle vehicle) {
    if (vehicle instanceof ElectricCar) {
        vehicle.chargeBattery();
    }
}
  • Review inheritance
public abstract class Vehicle {
  	//Common to each vehicles
    private boolean engineStarted = false;

    public void startEngine() {
        this.engineStarted = true;
    }

    public boolean engineIsStarted() {
        return engineStarted;
    }

    public void stopEngine() {
        this.engineStarted = false;
    }

  	//Force implementation -> should be isolated in interfaces
    public abstract void fillUpWithFuel();

    public abstract void chargeBattery();
}
  • Create Interfaces : ElectricityPowered, PetrolPowered
public class ElectricCar extends Vehicle implements ElectricityPowered
public class PetrolCar extends Vehicle implements PetrolPowered
  • Now we can refactor the FillingStation
public class FillingStation {

    public void refuel(PetrolCar petrolCar) {
        petrolCar.fillUpWithFuel();
    }

    public void charge(ElectricCar electricCar) {
        electricCar.chargeBattery();
    }
}
  • Create subtype of cars : VWDieselCar, TeslaCar for example
    • Use them in your tests
    • No more instanceof anywhere
    • More cleaner Inheritance

ISP

public class Bird implements Animal {
  	// exactly what we want to avoid
    public void bark() { }
    public void run() {
        System.out.print("Bird is running");
    }
    public void fly() {
        System.out.print("Bird is flying");
    }
}
  • Split the Animal interface : Barking, Running, Flying

    public interface Animal {
        void fly();
        void run();
        void bark();
    }
  • Change the Bird, Dog implements part

DIP

  • Find the code smell
public class BirthdayGreeter {
    private final EmployeeRepository employeeRepository;
    private final Clock clock;

    public BirthdayGreeter(EmployeeRepository employeeRepository, Clock clock) {
        this.employeeRepository = employeeRepository;
        this.clock = clock;
    }

    public void sendGreetings() {
        MonthDay today = clock.monthDay();
        employeeRepository.findEmployeesBornOn(today)
                .stream()
                .map(employee -> emailFor(employee))
          			// Ask questions about this line
                // Impact on testing
                .forEach(email -> new EmailSender().send(email));
    }

    private Email emailFor(Employee employee) {
        String message = String.format("Happy birthday, dear %s!", employee.getFirstName());
        return new Email(employee.getEmail(), "Happy birthday!", message);
    }

}
  • Inject the EmailSender
    • Ask question about how to do it : method, constructor, property
  • Impact on the tests ?
    • No more need to check stdout
    • Check call to EmailSender only
  • Demo of Lombok builder for emails