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
- Utworzyć interface
FlyweightDaneStale
- Utworzyć klasę
FlyweightFactory
z prywatnym konstruktorem. Klasa ta zawiera
klasę wewnętrznąFlyweight
implementującą FlyweightDaneStale
. Klasa ta umożliwia powstanie tylu instancjiFlyweight
ile jest oddziałów.FlyweightFactory udostępnia te instancje. Instancja
(singleton).FlyweightFactory
jest tylko jedna - 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 ----------------