Wzorzec projektowy Flyweight

Flyweight = waga (kategoria) musza.

Zadanie programistyczne

Smok planuje druk wizytówek dla osób zatrudnionych w firmie. Dane firmy
są stałe. Firma składa się z czterech oddziałów. Zmieniają się tylko dane pracownika
tj. imię i stanowisko. Dodawanie danych firmy do każdej wizytówki byłoby
zwykłym marnowaniem zasobów komputera.

Rozwiązanie

Wzorzec możemy zastosować na dwa sposoby.

Sposób 1

  1. Utworzyć interface FlyweightDaneStale
  2. Utworzyć klasę FlyweightFactory z prywatnym konstruktorem. Klasa ta zawiera
    klasę wewnętrzną Flyweight implementującą FlyweightDaneStale. Klasa ta umożliwia
    powstanie tylu instancji Flyweight ile jest oddziałów. FlyweightFactory
    udostępnia te instancje. Instancja FlyweightFactory jest tylko jedna

    (singleton).
  3. Utworzyć klasę testującą i przetestować wzorzec.
Klasa FlyweightDaneStale
package flyweight.flyweight1;
public interface FlyweightDaneStale {
    String getFirma();
    String getNumber();
    String getJaskinia();
    String getMiasto();
    String getKod();
    void print(String name, String title);
}
Klasa FlyweightFactory
package flyweight.flyweight1;
import java.util.*;
public class FlyweightFactory {
    private final HashMap<String, FlyweightDaneStale> flyweight;
    private static final FlyweightFactory factory = new FlyweightFactory();
    private FlyweightFactory() {
        flyweight = new HashMap<>();
    }
    public synchronized FlyweightDaneStale getFlyweight(String nazwaOddzialu) {
        if (flyweight.get(nazwaOddzialu) == null) {
            FlyweightDaneStale fwds = new Flyweight(nazwaOddzialu);
            flyweight.put(nazwaOddzialu, fwds);
            // System.out.println(fwds == null);
            return fwds;
        } else {
            return flyweight.get(nazwaOddzialu);
        }
    }
    public static FlyweightFactory getInstance() {
        return factory;
    }
    private class Flyweight implements FlyweightDaneStale {
        private String firma;
        private String number;
        private String jaskinia;
        private String miasto;
        private String kod;
        private void setValues(String firma, String number, String jaskinia, String miasto, String kod) {
            this.firma = firma;
            this.number = number;
            this.jaskinia = jaskinia;
            this.miasto = miasto;
            this.kod = kod;
        }
        private Flyweight(String oddzialFirmy) {
            if (oddzialFirmy.equals("North")) {
                setValues("Vollys North", "2", "jaskinia", "Vollystown", "10000");
            }
            if (oddzialFirmy.equals("South")) {
                setValues("Vollys South", "8", "jaskinia", "Vollysville", "20000");
            }
            if (oddzialFirmy.equals("East")) {
                setValues("Vollys East", "7", "jaskinia", "New Vollys", "30000");
            }
            if (oddzialFirmy.equals("West")) {
                setValues("Vollys West", "4", "grota", "Old Vollys", "40000");
            }
        }
        @Override
        public String getFirma() {
            return firma;
        }
        @Override
        public String getNumber() {
            return number;
        }
        @Override
        public String getJaskinia() {
            return jaskinia;
        }
        @Override
        public String getMiasto() {
            return miasto;
        }
        @Override
        public String getKod() {
            return kod;
        }
        @Override
        public void print(String imie, String stanowisko) {
            System.out.println(imie);
            System.out.println(stanowisko);
            System.out.println(getFirma());
            System.out.println(getJaskinia() + " " + getNumber());
            System.out.println(getKod() + " " + getMiasto());
            System.out.println("----------------");
        }
    }
}
Klasa Main1
package flyweight.flyweight1;
import java.util.*;
class Main1 {
    public static void main(String[] args) {
        Vector<String> listaPracownikow = initialize();
        FlyweightFactory factory = FlyweightFactory.getInstance();
        for (int i = 0; i < listaPracownikow.size(); i++) {
            String s = listaPracownikow.elementAt(i);
            StringTokenizer st = new StringTokenizer(s, ",");
            String imie = st.nextToken();
            String stanowisko = st.nextToken();
            String oddzial = st.nextToken();
            FlyweightDaneStale flyweight = factory.getFlyweight(oddzial);
            flyweight.print(imie, stanowisko);
        }
    }
    private static Vector<String> initialize() {
        Vector<String> v = new Vector<>();
        v.add("imie1,stanowisko1,North");
        v.add("imie2,stanowisko2,South");
        v.add("imie3,stanowisko1,North");
        v.add("imie4,stanowisko3,East");
        v.add("imie5,stanowisko4,East");
        v.add("imie6,stanowisko2,East");
        v.add("imie7,stanowisko1,West");
        v.add("imie8,stanowisko3,West");
        v.add("imie9,stanowisko1,West");
        v.add("imie10,stanowisko6,South");
        v.add("imie11,stanowisko5,North");
        v.add("imie12,stanowisko1,North");
        return v;
    }
}
Wynik
imie1
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie2
stanowisko2
Vollys South
jaskinia 8
20000 Vollysville
----------------
imie3
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie4
stanowisko3
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie5
stanowisko4
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie6
stanowisko2
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie7
stanowisko1
Vollys West
grota 4
40000 Old Vollys
----------------
imie8
stanowisko3
Vollys West
grota 4
40000 Old Vollys
----------------
imie9
stanowisko1
Vollys West
grota 4
40000 Old Vollys
----------------
imie10
stanowisko6
Vollys South
jaskinia 8
20000 Vollysville
----------------
imie11
stanowisko5
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie12
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------

Sposób 2

Tworzymy klasę Wizytowka. Obiekt tej klasy zawiera jeden z 4
obiektów Flyweight oraz dane zmienne pracownika.
Uwaga. Zmiana danych w jednym z 4 obiektów Flyweight zmienia dane
Flyweight we wszystkich wizytówkach.

Klasa Wizytowka
package flyweight.flyweight2;
class Wizytowka {
    private final String imie;
    private final String stanowisko;
    private final FlyweightDaneStale daneStale;
    public Wizytowka(String imie, String stanowisko, FlyweightDaneStale daneStale) {
        this.imie = imie;
        this.stanowisko = stanowisko;
        this.daneStale = daneStale;
    }
    public void print() {
        System.out.println(imie);
        System.out.println(stanowisko);
        System.out.println(daneStale.getFirma());
        System.out.println(daneStale.getJaskinia() + " " + daneStale.getNumber());
        System.out.println(daneStale.getKod() + " " + daneStale.getMiasto());
        System.out.println("----------------");
    }
}
Klasa FlyweightDaneStale
package flyweight.flyweight2;
public interface FlyweightDaneStale {
    String getFirma();
    String getNumber();
    String getJaskinia();
    String getMiasto();
    String getKod();
}
Klasa FlyweightFactory
package flyweight.flyweight2;
import java.util.*;
public class FlyweightFactory {
    private final HashMap<String, FlyweightDaneStale> flyweight;
    private static final FlyweightFactory factory = new FlyweightFactory();
    private FlyweightFactory() {
        flyweight = new HashMap<>();
    }
    public synchronized FlyweightDaneStale getFlyweight(String oddzial) {
        if (flyweight.get(oddzial) == null) {
            FlyweightDaneStale fwds = new Flyweight(oddzial);
            flyweight.put(oddzial, fwds);
            return fwds;
        } else {
            return flyweight.get(oddzial);
        }
    }
    public static FlyweightFactory getInstance() {
        return factory;
    }
    private class Flyweight implements FlyweightDaneStale {
        private String firma;
        private String number;
        private String jaskinia;
        private String miasto;
        private String kod;
        private void setValues(String firma, String number, String jaskinia, String miasto, String kod) {
            this.firma = firma;
            this.number = number;
            this.jaskinia = jaskinia;
            this.miasto = miasto;
            this.kod = kod;
        }
        private Flyweight(String oddzialFirmy) {
            if (oddzialFirmy.equals("North")) {
                setValues("Vollys North", "2", "jaskinia", "Vollystown", "10000");
            }
            if (oddzialFirmy.equals("South")) {
                setValues("Vollys South", "8", "jaskinia", "Vollysville", "20000");
            }
            if (oddzialFirmy.equals("East")) {
                setValues("Vollys East", "7", "jaskinia", "New Vollys", "30000");
            }
            if (oddzialFirmy.equals("West")) {
                setValues("Vollys West", "4", "grota", "Old Vollys", "40000");
            }
        }
        @Override
        public String getFirma() {
            return firma;
        }
        @Override
        public String getNumber() {
            return number;
        }
        @Override
        public String getJaskinia() {
            return jaskinia;
        }
        @Override
        public String getMiasto() {
            return miasto;
        }
        @Override
        public String getKod() {
            return kod;
        }
    }
}
Klasa Main2
package flyweight.flyweight2;
import java.util.*;
class Main2 {
    public static void main(String[] args) {
        Vector<String> empList = initialize();
        FlyweightFactory factory = FlyweightFactory.getInstance();
        for (int i = 0; i < empList.size(); i++) {
            String s = empList.elementAt(i);
            StringTokenizer st = new StringTokenizer(s, ",");
            String name = st.nextToken();
            String title = st.nextToken();
            String division = st.nextToken();
            FlyweightDaneStale flyweight = factory.getFlyweight(division);
            Wizytowka card = new Wizytowka(name, title, flyweight);
            card.print();
        }
    }
    private static Vector<String> initialize() {
        Vector<String> v = new Vector<>();
        v.add("imie1,stanowisko1,North");
        v.add("imie2,stanowisko2,South");
        v.add("imie3,stanowisko1,North");
        v.add("imie4,stanowisko3,East");
        v.add("imie5,stanowisko4,East");
        v.add("imie6,stanowisko2,East");
        v.add("imie7,stanowisko1,West");
        v.add("imie8,stanowisko3,West");
        v.add("imie9,stanowisko1,West");
        v.add("imie10,stanowisko6,South");
        v.add("imie11,stanowisko5,North");
        v.add("imie12,stanowisko1,North");
        return v;
    }
}
Wynik
imie1
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie2
stanowisko2
Vollys South
jaskinia 8
20000 Vollysville
----------------
imie3
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie4
stanowisko3
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie5
stanowisko4
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie6
stanowisko2
Vollys East
jaskinia 7
30000 New Vollys
----------------
imie7
stanowisko1
Vollys West
grota 4
40000 Old Vollys
----------------
imie8
stanowisko3
Vollys West
grota 4
40000 Old Vollys
----------------
imie9
stanowisko1
Vollys West
grota 4
40000 Old Vollys
----------------
imie10
stanowisko6
Vollys South
jaskinia 8
20000 Vollysville
----------------
imie11
stanowisko5
Vollys North
jaskinia 2
10000 Vollystown
----------------
imie12
stanowisko1
Vollys North
jaskinia 2
10000 Vollystown
----------------

Dodaj komentarz

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