Wzorzec projektowy Visitor

Visitor = wizytator, odwiedzający.

Zadanie programistyczne

Potrzebujemy klasy, której obiekt będzie odwiedzał obiekty innych klas i
i wykonywał na nich pewne operacje. Np. mamy klasę Pracownik i klasę dziedziczącą
Kierownik. Chcemy zsumować dni urlopu (albo zarobki, itd).

Rozwiązanie

Trzeba użyć wzorca Visitor (Wizytator).
Tworzymy klasę abstrakcyjną Visitor zawierająca metodę visit dla każdej klasy
którą będziemy wizytować (te klasy nie muszą być koniecznie ‘rodziną’. Mogą to być zupełnie nie związane klasy.
W klasie Pracownik oraz w klasie Kierownik dodajemy metodę accept dla tego Visitora. Tworzymy klasy konkretne dziedziczące po klasie abstrakcyjnej.
po jednej dla każdego wizytatora: pierwszy zlicza dni urlopu, drugi
zlicza dni urlopu oraz dni dodatkowego urlopu przysługującego kadrze
kierowniczej. Są to TotalUrlopVisitor i ZwyklyUrlopVisitor.
Tworzymy klasę Main w ktorej wskazujemy wszystkie obiekty do odwiedzenia
i uruchamiamy metodę accept() każdego obiektu.

Kody

Klasa Visitor
package visitor;
public abstract class Visitor {
    public abstract void visit(Pracownik pracownik);
    public abstract void visit(Kierownik kierownik);
}
Klasa TotalUrlopVisitor
package visitor;
public class TotalUrlopVisitor extends Visitor {
    private int sumaDni;
    public TotalUrlopVisitor() {
        sumaDni = 0;
    }
    public int getSumaDni() {
        return sumaDni;
    }
    @Override
    public void visit(Kierownik kierownik) {
        sumaDni += kierownik.getUrlop();
        sumaDni += kierownik.getUrlopDodatkowy();
    }
    @Override
    public void visit(Pracownik pracownik) {
        sumaDni += pracownik.getUrlop();
    }
}
Klasa ZwyklyUrlopVisitor
package visitor;
public class ZwyklyUrlopVisitor extends Visitor {
    private int sumaDni;
    public ZwyklyUrlopVisitor() {
        sumaDni = 0;
    }
    public int getSumaDni() {
        return sumaDni;
    }
    @Override
    public void visit(Kierownik kierownik) {
        sumaDni += kierownik.getUrlop();
    }
    @Override
    public void visit(Pracownik pracownik) {
        sumaDni += pracownik.getUrlop();
    }
}
Klasa Pracownik
package visitor;
public class Pracownik {
    private int zwolnienia, urlop;
    private double pensja;
    private String nazwisko;
    public Pracownik(String nazwisko, double pensja, int urlop, int zwolnienia) {
        this.urlop = urlop;
        this.zwolnienia = zwolnienia;
        this.pensja = pensja;
        this.nazwisko = nazwisko;
    }
    public int getZwolnienia() {
        return zwolnienia;
    }
    public void setZwolnienia(int zwolnienia) {
        this.zwolnienia = zwolnienia;
    }
    public int getUrlop() {
        return urlop;
    }
    public void setUrlop(int urlopy) {
        this.urlop = urlopy;
    }
    public double getPensja() {
        return pensja;
    }
    public void setPensja(double pensja) {
        this.pensja = pensja;
    }
    public String getNazwisko() {
        return nazwisko;
    }
    public void setNazwisko(String nazwisko) {
        this.nazwisko = nazwisko;
    }
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
Klasa Kierownik
package visitor;
public class Kierownik extends Pracownik {
    private int urlopDodatkowy;
    public Kierownik(String nazwisko, double pensja, int urlopy, int zwolnienia) {
        super(nazwisko, pensja, urlopy, zwolnienia);
    }
    public int getUrlopDodatkowy() {
        return urlopDodatkowy;
    }
    public void setUrlopDodatkowy(int urlopDodatkowy) {
        this.urlopDodatkowy = urlopDodatkowy;
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
Klasa Main
package visitor;
public class Main {
    private Pracownik[] pracownicy;
    public Main() {
        pracownicy = new Pracownik[7];
        int i = 0;
        pracownicy[i++] = new Pracownik("A.A.", 55000, 12, 1);
        pracownicy[i++] = new Pracownik("A.B.", 150000, 9, 0);
        pracownicy[i++] = new Pracownik("F.H", 50000, 15, 2);
        pracownicy[i++] = new Pracownik("D.O", 57000, 12, 2);
        pracownicy[i++] = new Pracownik("L. T", 100000, 20, 6);
        Kierownik b = new Kierownik("L.S", 175000, 16, 4);
        b.setUrlopDodatkowy(12);
        Kierownik b1 = new Kierownik("M.B", 35000, 17, 6);
        b1.setUrlopDodatkowy(17);
        pracownicy[i++] = b;
        pracownicy[i++] = b1;
        ZwyklyUrlopVisitor zuv = new ZwyklyUrlopVisitor();
        TotalUrlopVisitor vac = new TotalUrlopVisitor();
        for (int j = 0; j < pracownicy.length; j++) {
            pracownicy[j].accept(vac);
            pracownicy[j].accept(zuv);
        }
        System.out.println("Liczba wszystkich dni urlopu do wykorzystania: " + Integer.valueOf(vac.getSumaDni()));
        System.out.println("Liczba dni zwykłych do wykorzystania: " + Integer.valueOf(zuv.getSumaDni()));
    }
    // -----------------------------------------
    static public void main(String argv[]) {
        new Main();
    }
}

Wynik

Liczba wszystkich dni urlopu do wykorzystania: 130
Liczba dni zwykłych do wykorzystania: 101

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *