Описание: Паттерн Абстрактная фабрика предназначен для создания групп объектов, связанных между собой по смыслу. Например, каждая из реализаций Абстрактной фабрики может быть предназначена для определенной операционной системы. В качестве такой фабрики можно представить модель данных, реализации компонент которой могут меняться.
Паттерн Фабричный метод
Описание: Паттерн Фабричный метод необходим для ликвидирования зависимости кода от создания конкретных объектов. Создание экземпляра объекта выделяется в абстрактный метод фабрики, который реализуется потомком этой фабрики. В основу паттерна заложен принцип наследования. Пример:
1 2 3 4 5 6 |
public class Main { public static void main(String[] args){ ChineseFactory chineseFactory = new ChineseFactory(); chineseFactory.displayUnit(); } } |
1 2 3 4 |
Name: Chinese -_- /|\=|--- / \ |
Коды классов:
1 2 3 4 5 |
public interface Unit { String getName(); String getFace(); String getWeapon(); } |
1 2 3 4 5 6 7 8 9 10 |
public abstract class UnitFactory { public void displayUnit(){ Unit unit = getUnit(); System.out.println("Name: "+unit.getName()); System.out.println(unit.getFace()); System.out.println("/|\\"+unit.getWeapon()); System.out.println("/ \\"); } abstract Unit getUnit(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class ChineseFactory extends UnitFactory { @Override Unit getUnit() { return new Unit() { @Override public String getName() { return "Chinese"; } @Override public String getFace() { return "-_-"; } @Override public String getWeapon() { return "=|---"; } }; } } |
Паттерн Простая Фабрика
Описание: Паттерн Простая фабрика необходим для простой инкапсуляции процесса создания объектов от рабочего кода с помощью другого, отдельного класса. За простоту приходится платить минусом: мы привязываемся к определенной реализации и не можем обеспечить гибкость системы. Используйте этот паттерн только для
Паттерн Декоратор
Описание: Паттерн Декоратор необходим для построения систем-“матрёшек”, где каждый класс можно завернуть в другой, тем самым расширив его функционал. Расширение осуществляется посредством нехитрой композиции. Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Main { public static void main(String[] args){ Component computer = new Computer(); computer = new Keyboard(computer); computer = new Mouse(computer); computer = new Memory(computer); computer = new Memory(computer); System.out.println("Order for my computer"); for (String part : computer.getDescription()){ System.out.println("Component: "+part); } System.out.println("Total cost: "+computer.getCost()); } } |
1 2 3 4 5 6 7 |
Order for my computer Component: My computer Component: Logitech Keyboard K200 Component: SteelSeries Sensei MLG 62153 Black Component: Toshiba STOR.E 1TB Component: Toshiba STOR.E 1TB Total cost: 50270.0 |
Коды классов:
1 2 3 4 |
public interface Component { public ArrayList<string> getDescription(); public double getCost(); } |
1 2 3 |
public interface ComponentDecorator extends Component { public void setWrapped(Component c); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Computer implements Component { @Override public ArrayList<string> getDescription() { ArrayList<string> arrayList = new ArrayList<string>(); arrayList.add("My computer"); return arrayList; }</string></string></string> @Override public double getCost() { return 33000.0; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Keyboard implements ComponentDecorator { Component wrapped; public Keyboard(Component c){ setWrapped(c); } @Override public void setWrapped(Component c) { this.wrapped = c; } @Override public ArrayList<string> getDescription() { ArrayList<string> arrayList = wrapped.getDescription(); arrayList.add("Logitech Keyboard K200"); return arrayList; }</string></string> @Override public double getCost() { return wrapped.getCost() + 820.; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Mouse implements ComponentDecorator { Component wrapped; public Mouse(Component c){ setWrapped(c); } @Override public void setWrapped(Component c) { this.wrapped = c; } @Override public ArrayList<string> getDescription() { ArrayList<string> arrayList = wrapped.getDescription(); arrayList.add("SteelSeries Sensei MLG 62153 Black"); return arrayList; }</string></string> @Override public double getCost() { return wrapped.getCost() + 7190.; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class Memory implements ComponentDecorator { Component wrapped; public Memory(Component c){ setWrapped(c); } @Override public void setWrapped(Component c) { this.wrapped = c; } @Override public ArrayList<string> getDescription() { ArrayList<string> arrayList = wrapped.getDescription(); arrayList.add("Toshiba STOR.E 1TB"); return arrayList; }</string></string> @Override public double getCost() { return wrapped.getCost() + 4630.; } } |
UML-диаграмма: Паттерн Декоратор используется в
Паттерн Наблюдатель
Описание: Паттрен Наблюдатель необходим для создания слабосвязанного взаимодействия субъекта (самолет, космический корабль и другие субъекты, имеющие состояние) с наблюдателями (монитор, чёрный ящик или другой объект, использующий информацию о субъекте по-своему). Паттерн Наблюдатель реализует отношение “один ко многим”. Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Main { public static void main(String[] args){ SpaceShipData spaceShipData = new SpaceShipData(); SpaceDisplay spaceDisplay = new SpaceDisplay(spaceShipData); spaceShipData.setParameters(0,SpaceShipData.SHIELD_ON,new int[]{0,0,0}); spaceShipData.setParameters(100,SpaceShipData.SHIELD_OFF, new int[]{1000,300,100}); spaceDisplay.unSubscribe(); spaceShipData.setParameters(100000,SpaceShipData.SHIELD_ON, new int[]{500000,780,123}); } } |
1 2 3 4 5 6 |
Current velocity: 0 Coordinates: X=0 Y=0 Z=0 Shield status: 0 Current velocity: 100 Coordinates: X=1000 Y=300 Z=100 Shield status: 1 |
Паттерн Стратегия
Описание: Инкапсулируем поведенческие семейства алгоритмов в отдельные классы, реализующие общий интерфейс. Это позволяет изменять аспекты объекта во время выполнения программы. Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Main { public static void main(String[] args){ Hero hero = new Knight("Obi Wan"); hero.printName(); Knight knight = new Knight("Dart Sitius"); knight.printName(); hero.getWeapon().damage(knight); knight.printHealth(); hero.setWeapon(new Laser()); for (int i = 0; i < 4; i++){ hero.getWeapon().damage(knight); knight.printHealth(); } } } |
1 2 3 4 5 6 7 |
My name is Obi Wan My name is Dart Sitius Dart Sitius health: 90% Dart Sitius health: 80% Dart Sitius health: 60% Dart Sitius health: 30% Dart Sitius is dead. |
Коды классов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
abstract class Hero { String name; int health; Weapon weapon; public Hero(String name){ health = 100; this.name = new String(name); } public void printName(){ System.out.println("My name is " + name); } public void printHealth(){ if (health != 0) { System.out.println(name + " health: " + health + "%"); }else{ System.out.println(name+" is dead."); } } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; if (this.health < 0){ this.health = 0; } } public Weapon getWeapon() { return weapon; } public void setWeapon(Weapon weapon) { this.weapon = weapon; } } |
1 2 3 4 5 6 7 |
public class Knight extends Hero{ public Knight(String name) { super(name); setWeapon(new Sword()); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Laser implements Weapon{ private int power = 10; @Override public void damage(Hero hero) { hero.setHealth(hero.getHealth()-getWeaponPower()); power += 10; //увеличиваем мощность каждую секунду } @Override public int getWeaponPower() { return power; } } public class Sword implements Weapon { private int power = 10; @Override public void damage(Hero hero) { hero.setHealth(hero.getHealth()-getWeaponPower()); } @Override public int getWeaponPower() { return power; } } |
1 2 3 4 |
public interface Weapon { public void damage(Hero hero); public int getWeaponPower(); } |
UML-диаграмма: Универсальный совет: отдавайте предпочтение интерфейсу, нежели абстрактному классу