-2

I have classes Dog, Cat, ... extends of Pet and init method. How to eliminate duplicate code, if init method must be void.

public class Tester {
    private Pet pet1;
    private Pet pet2;
    private int i;

    public void pet1Init(){
        switch (i){
            case 0:
                pet1 = new Cat();
                break;
            case 1:
                pet1 = new Dog();
                break;
            .....
        }
    }

    public void pet2Init(){
        switch (i){
            case 0:
                pet2 = new Cat();
                break;
            case 1:
                pet2 = new Dog();
                break;
            .......
        }
    }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Vadim
  • 557
  • 8
  • 21

1 Answers1

0

I'll give you a solution not changing your design to see how awkward it is:

public void pet1Init(){
    pet1 = getPet().get();
}

public void pet2Init(){
    pet2 = getPet().get();
}

private Supplier<Pet> getPet() {
    Supplier<Pet> supplier = Cat::new; // default pet

    switch (i){
        case 0:
            supplier = Cat::new;
            break;
        case 1:
            supplier = Dog::new;
            break;
    }

    return supplier;
}

A bit cleaner solution uses a Map<Integer, Supplier<Pet>>:

private Map<Integer, Supplier<Pet>> map = Map.of(0, Cat::new, 1, Dog::new);

private Supplier<Pet> getPet() {
    return map.getOrDefault(i, Cat::new);
}

Though, it's still unclear what you are trying to achieve. These variables can be initialised within a single method since they share the same algorithm:

public void initialisePets(){
    final Supplier<Pet> supplier = getPet();

    pet1 = supplier.get();
    pet2 = supplier.get();
}
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142