Учебники

Краткое руководство по шаблону дизайна

Шаблоны проектирования представляют лучшие практики, используемые опытными разработчиками объектно-ориентированного программного обеспечения. Шаблоны проектирования — это решение общих проблем, с которыми разработчики программного обеспечения сталкивались при разработке программного обеспечения. Эти решения были получены методом проб и ошибок многочисленными разработчиками программного обеспечения в течение довольно значительного периода времени.

Что такое Банда Четырех (GOF)?

В 1994 году четыре автора: Эрих Гамма, Ричард Хелм, Ральф Джонсон и Джон Влиссидес опубликовали книгу под названием « Шаблоны проектирования — элементы многоразового объектно-ориентированного программного обеспечения», которая положила начало концепции «Шаблон проектирования» в разработке программного обеспечения.

Эти авторы известны под общим названием Gang of Four (GOF) . По мнению этих авторов, шаблоны проектирования в первую очередь основаны на следующих принципах объектно-ориентированного проектирования.

  • Программа для интерфейса не реализация

  • Пользуешься композицией объекта по наследству

Программа для интерфейса не реализация

Пользуешься композицией объекта по наследству

Использование шаблона проектирования

Шаблоны проектирования имеют два основных применения в разработке программного обеспечения.

Общая платформа для разработчиков

Шаблоны проектирования предоставляют стандартную терминологию и специфичны для конкретного сценария. Например, шаблон одноэлементного проектирования означает использование одного объекта, поэтому все разработчики, знакомые с одним шаблоном проектирования, будут использовать один объект и могут сообщать друг другу, что программа следует одноэлементному шаблону.

Лучшие практики

Шаблоны проектирования развивались в течение длительного периода времени, и они обеспечивают наилучшие решения определенных проблем, возникающих при разработке программного обеспечения. Изучение этих шаблонов помогает неопытным разработчикам изучать дизайн программного обеспечения простым и быстрым способом.

Типы дизайна шаблона

Согласно справочнику шаблонов проектирования «Шаблоны проектирования — элементы многоразового объектно-ориентированного программного обеспечения» , существует 23 шаблона проектирования. Эти шаблоны можно классифицировать по трем категориям: творческие, структурные и поведенческие. Мы также обсудим еще одну категорию шаблонов проектирования: шаблоны проектирования J2EE.

SN Шаблон и описание
1 Образцы творчества
Эти шаблоны проектирования позволяют создавать объекты, скрывая логику создания, а не создавать объекты непосредственно с помощью оператора new. Это дает программе большую гибкость в определении того, какие объекты необходимо создать для данного варианта использования.
2 Структурные паттерны
Эти шаблоны проектирования относятся к классу и составу объекта. Концепция наследования используется для составления интерфейсов и определения способов составления объектов для получения новых функциональных возможностей.
3 Поведенческие образцы
Эти шаблоны проектирования конкретно связаны со связью между объектами.
4 Шаблоны J2EE
Эти шаблоны проектирования специально связаны с уровнем представления. Эти шаблоны определены Sun Java Center.

Фабричный образец

Фабричный шаблон является одним из наиболее часто используемых шаблонов проектирования в Java. Этот тип шаблона проектирования подпадает под шаблон создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.

В шаблоне Factory мы создаем объект без предоставления клиенту логики создания и обращаемся к вновь созданному объекту, используя общий интерфейс.

Реализация

Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . Фабричный класс ShapeFactory определяется как следующий шаг.

FactoryPatternDemo , наш демонстрационный класс будет использовать ShapeFactory для получения объекта Shape . Он будет передавать информацию ( CIRCLE / RECTANGLE / SQUARE ) в ShapeFactory, чтобы получить тип объекта, который ему нужен.

UML диаграмма

Шаг 1

Создать интерфейс.

Shape.java

public interface Shape {
   void draw();
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Шаг 3

Создать Фабрику для генерации объекта конкретного класса на основе заданной информации.

ShapeFactory.java

public class ShapeFactory {
	
   //use getShape method to get object of type shape 
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }		
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

Шаг 4

Используйте Фабрику, чтобы получить объект конкретного класса, передавая информацию, такую ​​как тип.

FactoryPatternDemo.java

public class FactoryPatternDemo {

   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();

      //get an object of Circle and call its draw method.
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //call draw method of Circle
      shape1.draw();

      //get an object of Rectangle and call its draw method.
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Rectangle
      shape2.draw();

      //get an object of Square and call its draw method.
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of square
      shape3.draw();
   }
}

Шаг 5

Проверьте вывод.

 Внутри Circle :: draw () метод.
 Внутри Rectangle :: draw () метод.
 Внутри Square :: draw () метод.

Шаблон дизайна — абстрактный шаблон фабрики

Абстрактные фабричные шаблоны работают вокруг суперфабрики, которая создает другие фабрики. Эта фабрика также называется фабрикой фабрик. Этот тип шаблона проектирования подпадает под шаблон создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.

В шаблоне Abstract Factory интерфейс отвечает за создание фабрики связанных объектов без явного указания их классов. Каждая сгенерированная фабрика может давать объекты в соответствии с шаблоном фабрики.

Реализация

Мы собираемся создать интерфейсы Shape и Color и конкретные классы, реализующие эти интерфейсы. В качестве следующего шага мы создадим абстрактный фабричный класс AbstractFactory . Фабричные классы ShapeFactory и ColorFactory определяются там, где каждая фабрика расширяет AbstractFactory . Создатель фабрики / генератор класса FactoryProducer создан.

AbstractFactoryPatternDemo , наш демонстрационный класс использует FactoryProducer для получения объекта AbstractFactory . Он будет передавать информацию ( CIRCLE / RECTANGLE / SQUARE для Shape ) в AbstractFactory для получения нужного типа объекта. Он также передает информацию ( RED / GREEN / BLUE для Color ) в AbstractFactory для получения нужного типа объекта.

Абстрактная фабричная модель UML-диаграммы

Шаг 1

Создайте интерфейс для форм и цветов.

Shape.java

public interface Shape {
   void draw();
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

RoundedRectangle.java

public class RoundedRectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside RoundedRectangle::draw() method.");
   }
}

RoundedSquare.java

public class RoundedSquare implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside RoundedSquare::draw() method.");
   }
}

Rectangle.java

public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Шаг 3

Создайте абстрактный класс, чтобы получить фабрики для объектов нормальной и округлой формы.

AbstractFactory.java

public abstract class AbstractFactory {
   abstract Shape getShape(String shapeType) ;
}

Шаг 4

Создать классы Factory, расширяющие AbstractFactory для генерации объекта конкретного класса на основе заданной информации.

ShapeFactory.java

public class ShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }	 
      return null;
   }
}

RoundedShapeFactory.java

public class RoundedShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new RoundedRectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new RoundedSquare();
      }	 
      return null;
   }
}

Шаг 5

Создайте класс генератора / производителя фабрики, чтобы получить фабрики, передавая информацию, такую ​​как форма

FactoryProducer.java

public class FactoryProducer {
   public static AbstractFactory getFactory(boolean rounded){   
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
   }
}

Шаг 6

Используйте FactoryProducer для получения AbstractFactory, чтобы получить фабрики конкретных классов, передавая информацию, такую ​​как тип.

AbstractFactoryPatternDemo.java

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      //get rounded shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
      //get an object of Shape Rounded Rectangle
      Shape shape1 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape1.draw();
      //get an object of Shape Rounded Square 
      Shape shape2 = shapeFactory.getShape("SQUARE");
      //call draw method of Shape Square
      shape2.draw();
      //get rounded shape factory
      AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
      //get an object of Shape Rectangle
      Shape shape3 = shapeFactory1.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape3.draw();
      //get an object of Shape Square 
      Shape shape4 = shapeFactory1.getShape("SQUARE");
      //call draw method of Shape Square
      shape4.draw();
      
   }
}

Шаг 7

Проверьте вывод.

Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside RoundedRectangle::draw() method.
Inside RoundedSquare::draw() method.

Синглтон

Шаблон Singleton — один из самых простых шаблонов проектирования в Java. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.

Этот шаблон включает в себя один класс, который отвечает за создание собственного объекта, обеспечивая при этом создание только одного объекта. Этот класс предоставляет способ доступа к своему единственному объекту, к которому можно получить непосредственный доступ без необходимости создания экземпляра объекта класса.

Реализация

Мы собираемся создать класс SingleObject . Класс SingleObject имеет свой конструктор как закрытый и имеет статический экземпляр.

Класс SingleObject предоставляет статический метод для передачи своего статического экземпляра во внешний мир. SingletonPatternDemo , наш демонстрационный класс будет использовать класс SingleObject для получения объекта SingleObject .

UML-диаграмма синглтон-паттерна

Шаг 1

Создать синглтон-класс.

SingleObject.java

public class SingleObject {

   //create an object of SingleObject
   private static SingleObject instance = new SingleObject();

   //make the constructor private so that this class cannot be
   //instantiated
   private SingleObject(){}

   //Get the only object available
   public static SingleObject getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

Шаг 2

Получить единственный объект из класса синглтона.

SingletonPatternDemo.java

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();

      //show the message
      object.showMessage();
   }
}

Шаг 3

Проверьте вывод.

 Привет, мир!

Образец Строителя

Шаблон Builder создает сложный объект, используя простые объекты и используя пошаговый подход. Этот тип шаблона проектирования подпадает под шаблон создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.

Класс Builder строит конечный объект шаг за шагом. Этот строитель не зависит от других объектов.

Реализация

Мы рассмотрели бизнес-пример ресторана быстрого питания, где типичной едой может быть гамбургер и холодный напиток. Бургер может быть как вегетарианским, так и куриным, и его можно упаковывать в обертку. Холодный напиток может быть как колой, так и пепси, и будет упакован в бутылку.

Мы собираемся создать интерфейс Item, представляющий продукты питания, такие как гамбургеры и холодные напитки и классы бетона, реализующие интерфейс Item, и интерфейс Packing, представляющий упаковку продуктов питания, и конкретные классы, реализующие интерфейс упаковки, так как бургер будет упакован в обертку и холодную упаковку. напиток будет упакован как бутылка.

Затем мы создаем класс Meal с ArrayList of Item и MealBuilder для создания различных типов объектов Meal путем объединения Item . BuilderPatternDemo , наш демонстрационный класс будет использовать MealBuilder для создания Meal .

UML Диаграмма Построителя

Шаг 1

Создайте интерфейс Item, представляющий продукт питания и упаковку.

Item.java

public interface Item {
   public String name();
   public Packing packing();
   public float price();	
}

Packing.java

public interface Packing {
   public String pack();
}

Шаг 2

Создать конкретные классы, реализующие интерфейс Packing.

Wrapper.java

public class Wrapper implements Packing {

   @Override
   public String pack() {
      return "Wrapper";
   }
}

Bottle.java

public class Bottle implements Packing {

   @Override
   public String pack() {
      return "Bottle";
   }
}

Шаг 3

Создайте абстрактные классы, реализующие интерфейс элемента с функциями по умолчанию.

Burger.java

public abstract class Burger implements Item {

   @Override
   public Packing packing() {
      return new Wrapper();
   }

   @Override
   public abstract float price();
}

ColdDrink.java

public abstract class ColdDrink implements Item {

	@Override
	public Packing packing() {
       return new Bottle();
	}

	@Override
	public abstract float price();
}

Шаг 4

Создание конкретных классов, расширяющих классы Burger и ColdDrink.

VegBurger.java

public class VegBurger extends Burger {

   @Override
   public float price() {
      return 25.0f;
   }

   @Override
   public String name() {
      return "Veg Burger";
   }
}

ChickenBurger.java

public class ChickenBurger extends Burger {

   @Override
   public float price() {
      return 50.5f;
   }

   @Override
   public String name() {
      return "Chicken Burger";
   }
}

Coke.java

public class Coke extends ColdDrink {

   @Override
   public float price() {
      return 30.0f;
   }

   @Override
   public String name() {
      return "Coke";
   }
}

Pepsi.java

public class Pepsi extends ColdDrink {

   @Override
   public float price() {
      return 35.0f;
   }

   @Override
   public String name() {
      return "Pepsi";
   }
}

Шаг 5

Создайте класс Meal, имеющий объекты Item, определенные выше.

Meal.java

import java.util.ArrayList;
import java.util.List;

public class Meal {
   private List<Item> items = new ArrayList<Item>();	

   public void addItem(Item item){
      items.add(item);
   }

   public float getCost(){
      float cost = 0.0f;
      for (Item item : items) {
         cost += item.price();
      }		
      return cost;
   }

   public void showItems(){
      for (Item item : items) {
         System.out.print("Item : "+item.name());
         System.out.print(", Packing : "+item.packing().pack());
         System.out.println(", Price : "+item.price());
      }		
   }	
}

Шаг 6

Создайте класс MealBuilder, фактический класс строителя, ответственный за создание объектов Meal.

MealBuilder.java

public class MealBuilder {

   public Meal prepareVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new VegBurger());
      meal.addItem(new Coke());
      return meal;
   }   

   public Meal prepareNonVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new ChickenBurger());
      meal.addItem(new Pepsi());
      return meal;
   }
}

Шаг 7

BuiderPatternDemo использует MealBuider для демонстрации шаблона компоновщика.

BuilderPatternDemo.java

public class BuilderPatternDemo {
   public static void main(String[] args) {
      MealBuilder mealBuilder = new MealBuilder();

      Meal vegMeal = mealBuilder.prepareVegMeal();
      System.out.println("Veg Meal");
      vegMeal.showItems();
      System.out.println("Total Cost: " +vegMeal.getCost());

      Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
      System.out.println("\n\nNon-Veg Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " +nonVegMeal.getCost());
   }
}

Шаг 8

Проверьте вывод.

 Овощная мука
 Пункт: Овощной бургер, Упаковка: Обертка, Цена: 25.0
 Пункт: Кокс, Упаковка: Бутылка, Цена: 30,0
 Общая стоимость: 55.0

 Не вегетарианская еда
 Пункт: Куриный бургер, Упаковка: Обертка, Цена: 50,5
 Пункт: Пепси, Упаковка: Бутылка, Цена: 35.0
 Общая стоимость: 85,5

Образец прототипа

Образец прототипа относится к созданию дублирующегося объекта с учетом производительности. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.

Этот шаблон включает в себя реализацию интерфейса прототипа, который говорит, чтобы создать клон текущего объекта. Этот шаблон используется, когда создание объекта напрямую является дорогостоящим. Например, объект должен быть создан после дорогостоящей операции с базой данных. Мы можем кэшировать объект, возвращать его клон при следующем запросе и обновлять базу данных по мере необходимости, уменьшая количество вызовов базы данных.

Реализация

Мы собираемся создать абстрактный класс Shape и конкретные классы, расширяющие класс Shape . Класс ShapeCache определяется как следующий шаг, который сохраняет объекты формы в Hashtable и возвращает их клон по запросу.

PrototypPatternDemo , наш демонстрационный класс будет использовать класс ShapeCache для получения объекта Shape .

UML Диаграмма прототипа

Шаг 1

Создайте абстрактный класс, реализующий интерфейс Clonable .

Shape.java

public abstract class Shape implements Cloneable {
   
   private String id;
   protected String type;
   
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId() {
      return id;
   }
   
   public void setId(String id) {
      this.id = id;
   }
   
   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}

Шаг 2

Создайте конкретные классы, расширяющие вышеуказанный класс.

Rectangle.java

public class Rectangle extends Shape {

   public Rectangle(){
     type = "Rectangle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Square.java

public class Square extends Shape {

   public Square(){
     type = "Square";
   }

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle.java

public class Circle extends Shape {

   public Circle(){
     type = "Circle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Шаг 3

Создайте класс для получения конкретных классов из базы данных и сохраните их в Hashtable .

ShapeCache.java

import java.util.Hashtable;

public class ShapeCache {
	
   private static Hashtable<String, Shape> shapeMap 
      = new Hashtable<String, Shape>();

   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }

   // for each shape run database query and create shape
   // shapeMap.put(shapeKey, shape);
   // for example, we are adding three shapes
   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);

      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);

      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(),rectangle);
   }
}

Шаг 4

PrototypePatternDemo использует класс ShapeCache для получения клонов фигур, хранящихся в Hashtable .

PrototypePatternDemo.java

public class PrototypePatternDemo {
   public static void main(String[] args) {
      ShapeCache.loadCache();

      Shape clonedShape = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());		

      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());		

      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());		
   }
}

Шаг 5

Проверьте вывод.

 Форма: круг
 Форма: Квадрат
 Форма: прямоугольник

Шаблон адаптера

Шаблон адаптера работает как мост между двумя несовместимыми интерфейсами. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон сочетает в себе возможности двух независимых интерфейсов.

Этот шаблон включает в себя один класс, который отвечает за объединение функций независимых или несовместимых интерфейсов. Примером из реальной жизни может служить устройство для чтения карт памяти, которое служит адаптером между картой памяти и ноутбуком. Вы вставляете карту памяти в устройство чтения карт и устройство чтения карт в ноутбук, чтобы можно было читать карту памяти через ноутбук.

Мы демонстрируем использование шаблона адаптера на следующем примере, в котором устройство аудиопроигрывателя может воспроизводить только файлы mp3 и хочет использовать усовершенствованный аудиопроигрыватель, способный воспроизводить файлы vlc и mp4.

Реализация

У нас есть интерфейс интерфейса MediaPlayer и конкретный класс AudioPlayer, реализующий интерфейс MediaPlayer . AudioPlayer может воспроизводить аудиофайлы в формате mp3 по умолчанию.

У нас есть другой интерфейс AdvancedMediaPlayer и конкретные классы, реализующие интерфейс AdvancedMediaPlayer. Эти классы могут воспроизводить файлы формата vlc и mp4.

Мы хотим, чтобы AudioPlayer воспроизводил и другие форматы. Для этого мы создали класс адаптера MediaAdapter, который реализует интерфейс MediaPlayer и использует объекты AdvancedMediaPlayer для воспроизведения требуемого формата.

AudioPlayer использует класс адаптера MediaAdapter, передавая ему нужный тип аудио, не зная фактического класса, который может воспроизводить нужный формат. AdapterPatternDemo , наш демонстрационный класс будет использовать класс AudioPlayer для воспроизведения различных форматов.

UML-схема шаблона адаптера

Шаг 1

Создайте интерфейсы для Media Player и Advanced Media Player.

MediaPlayer.java

public interface MediaPlayer {
   public void play(String audioType, String fileName);
}

AdvancedMediaPlayer.java

public interface AdvancedMediaPlayer {	
   public void playVlc(String fileName);
   public void playMp4(String fileName);
}

Шаг 2

Создайте конкретные классы, реализующие интерфейс AdvancedMediaPlayer .

VlcPlayer.java

public class VlcPlayer implements AdvancedMediaPlayer{
   @Override
   public void playVlc(String fileName) {
      System.out.println("Playing vlc file. Name: "+ fileName);		
   }

   @Override
   public void playMp4(String fileName) {
      //do nothing
   }
}

Mp4Player.java

public class Mp4Player implements AdvancedMediaPlayer{

   @Override
   public void playVlc(String fileName) {
      //do nothing
   }

   @Override
   public void playMp4(String fileName) {
      System.out.println("Playing mp4 file. Name: "+ fileName);		
   }
}

Шаг 3

Создайте класс адаптера, реализующий интерфейс MediaPlayer .

MediaAdapter.java

public class MediaAdapter implements MediaPlayer {

   AdvancedMediaPlayer advancedMusicPlayer;

   public MediaAdapter(String audioType){
      if(audioType.equalsIgnoreCase("vlc") ){
         advancedMusicPlayer = new VlcPlayer();			
      } else if (audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer = new Mp4Player();
      }	
   }

   @Override
   public void play(String audioType, String fileName) {
      if(audioType.equalsIgnoreCase("vlc")){
         advancedMusicPlayer.playVlc(fileName);
      }else if(audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer.playMp4(fileName);
      }
   }
}

Шаг 4

Создать конкретный класс, реализующий интерфейс MediaPlayer .

AudioPlayer.java

public class AudioPlayer implements MediaPlayer {
   MediaAdapter mediaAdapter; 

   @Override
   public void play(String audioType, String fileName) {		

      //inbuilt support to play mp3 music files
      if(audioType.equalsIgnoreCase("mp3")){
         System.out.println("Playing mp3 file. Name: "+ fileName);			
      } 
      //mediaAdapter is providing support to play other file formats
      else if(audioType.equalsIgnoreCase("vlc") 
         || audioType.equalsIgnoreCase("mp4")){
         mediaAdapter = new MediaAdapter(audioType);
         mediaAdapter.play(audioType, fileName);
      }
      else{
         System.out.println("Invalid media. "+
            audioType + " format not supported");
      }
   }   
}

Шаг 5

Используйте AudioPlayer для воспроизведения различных типов аудиоформатов.

AdapterPatternDemo.java

public class AdapterPatternDemo {
   public static void main(String[] args) {
      AudioPlayer audioPlayer = new AudioPlayer();

      audioPlayer.play("mp3", "beyond the horizon.mp3");
      audioPlayer.play("mp4", "alone.mp4");
      audioPlayer.play("vlc", "far far away.vlc");
      audioPlayer.play("avi", "mind me.avi");
   }
}

Шаг 6

Проверьте вывод.

 Воспроизведение mp3 файла.  Название: за горизонтом.mp3
 Воспроизведение файла mp4.  Название: alone.mp4
 Воспроизведение файла VLC.  Имя: далеко-далеко.vlc
 Неверный медиа.  AVI формат не поддерживается

Образец моста

Мост используется там, где нам нужно отделить абстракцию от его реализации, чтобы они могли различаться независимо друг от друга. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон разделяет класс реализации и абстрактный класс, предоставляя мостовую структуру между ними.

Этот шаблон включает интерфейс, который действует как мост, который делает функциональность конкретных классов независимой от классов реализации интерфейса. Оба типа классов могут быть изменены структурно, не влияя друг на друга.

Мы демонстрируем использование шаблона Bridge с помощью следующего примера, в котором круг может быть нарисован разными цветами, используя один и тот же метод абстрактного класса, но разные классы реализации моста.

Реализация

У нас есть интерфейс DrawAPI интерфейса, который выполняет функции моста и конкретные классы RedCircle , GreenCircle, реализующий интерфейс DrawAPI . Shape является абстрактным классом и будет использовать объект DrawAPI . BridgePatternDemo , наш демонстрационный класс будет использовать класс Shape для рисования разноцветного круга.

UML Диаграмма Мостового Узора

Шаг 1

Создать интерфейс реализации моста.

DrawAPI.java

public interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

Шаг 2

Создайте классы реализации конкретного моста, реализующие интерфейс DrawAPI .

RedCircle.java

public class RedCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: red, radius: "
         + radius +", x: " +x+", "+ y +"]");
   }
}

GreenCircle.java

public class GreenCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: green, radius: "
         + radius +", x: " +x+", "+ y +"]");
   }
}

Шаг 3

Создайте абстрактный класс Shape, используя интерфейс DrawAPI .

Shape.java

public abstract class Shape {
   protected DrawAPI drawAPI;
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();	
}

Шаг 4

Создайте конкретный класс, реализующий интерфейс Shape .

Circle.java

public class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }

   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

Шаг 5

Используйте классы Shape и DrawAPI для рисования разноцветных кругов.

BridgePatternDemo.java

public class BridgePatternDemo {
   public static void main(String[] args) {
      Shape redCircle = new Circle(100,100, 10, new RedCircle());
      Shape greenCircle = new Circle(100,100, 10, new GreenCircle());

      redCircle.draw();
      greenCircle.draw();
   }
}

Шаг 6

Проверьте вывод.

 Круг для рисования [цвет: красный, радиус: 10, х: 100, 100]
 Круг для рисования [цвет: зеленый, радиус: 10, х: 100, 100]

Шаблон фильтра / критериев

Шаблон фильтра или шаблон Критерии — это шаблон проекта, который позволяет разработчикам фильтровать набор объектов по различным критериям, связывая их в цепочке с помощью логических операций. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон объединяет несколько критериев для получения единых критериев.

Реализация

Мы собираемся создать объект Person , интерфейс Criteria и конкретные классы, реализующие этот интерфейс для фильтрации списка объектов Person . CriteriaPatternDemo , наш демонстрационный класс использует объекты Criteria для фильтрации объектов List of Person на основе различных критериев и их комбинаций.

Шаблон фильтра UML Диаграмма

Шаг 1

Создайте класс, по которому должны применяться критерии.

Person.java

public class Person {
	
   private String name;
   private String gender;
   private String maritalStatus;

   public Person(String name,String gender,String maritalStatus){
      this.name = name;
      this.gender = gender;
      this.maritalStatus = maritalStatus;		
   }

   public String getName() {
      return name;
   }
   public String getGender() {
      return gender;
   }
   public String getMaritalStatus() {
      return maritalStatus;
   }	
}

Шаг 2

Создать интерфейс для критериев.

Criteria.java

import java.util.List;

public interface Criteria {
   public List<Person> meetCriteria(List<Person> persons);
}

Шаг 3

Создать конкретные классы, реализующие интерфейс Criteria .

CriteriaMale.java

import java.util.ArrayList;
import java.util.List;

public class CriteriaMale implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> malePersons = new ArrayList<Person>(); 
      for (Person person : persons) {
         if(person.getGender().equalsIgnoreCase("MALE")){
            malePersons.add(person);
         }
      }
      return malePersons;
   }
}

CriteriaFemale.java

import java.util.ArrayList;
import java.util.List;

public class CriteriaFemale implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> femalePersons = new ArrayList<Person>(); 
      for (Person person : persons) {
         if(person.getGender().equalsIgnoreCase("FEMALE")){
            femalePersons.add(person);
         }
      }
      return femalePersons;
   }
}

CriteriaSingle.java

import java.util.ArrayList;
import java.util.List;

public class CriteriaSingle implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> singlePersons = new ArrayList<Person>(); 
      for (Person person : persons) {
         if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
            singlePersons.add(person);
         }
      }
      return singlePersons;
   }
}

AndCriteria.java

import java.util.List;

public class AndCriteria implements Criteria {

   private Criteria criteria;
   private Criteria otherCriteria;

   public AndCriteria(Criteria criteria, Criteria otherCriteria) {
      this.criteria = criteria;
      this.otherCriteria = otherCriteria; 
   }

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);		
      return otherCriteria.meetCriteria(firstCriteriaPersons);
   }
}

OrCriteria.java

import java.util.List;

public class AndCriteria implements Criteria {

   private Criteria criteria;
   private Criteria otherCriteria;

   public AndCriteria(Criteria criteria, Criteria otherCriteria) {
      this.criteria = criteria;
      this.otherCriteria = otherCriteria; 
   }

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
      List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

      for (Person person : otherCriteriaItems) {
         if(!firstCriteriaItems.contains(person)){
	        firstCriteriaItems.add(person);
         }
      }	
      return firstCriteriaItems;
   }
}

Step4

Используйте разные критерии и их комбинации, чтобы отфильтровать людей.

CriteriaPatternDemo.java

import java.util.ArrayList;
import java.util.List;

public class CriteriaPatternDemo {
   public static void main(String[] args) {
      List<Person> persons = new ArrayList<Person>();

      persons.add(new Person("Robert","Male", "Single"));
      persons.add(new Person("John","Male", "Married"));
      persons.add(new Person("Laura","Female", "Married"));
      persons.add(new Person("Diana","Female", "Single"));
      persons.add(new Person("Mike","Male", "Single"));
      persons.add(new Person("Bobby","Male", "Single"));

      Criteria male = new CriteriaMale();
      Criteria female = new CriteriaFemale();
      Criteria single = new CriteriaSingle();
      Criteria singleMale = new AndCriteria(single, male);
      Criteria singleOrFemale = new OrCriteria(single, female);

      System.out.println("Males: ");
      printPersons(male.meetCriteria(persons));

      System.out.println("\nFemales: ");
      printPersons(female.meetCriteria(persons));

      System.out.println("\nSingle Males: ");
      printPersons(singleMale.meetCriteria(persons));

      System.out.println("\nSingle Or Females: ");
      printPersons(singleOrFemale.meetCriteria(persons));
   }

   public static void printPersons(List<Person> persons){
      for (Person person : persons) {
         System.out.println("Person : [ Name : " + person.getName() 
            +", Gender : " + person.getGender() 
            +", Marital Status : " + person.getMaritalStatus()
            +" ]");
      }
   }      
}

Шаг 5

Проверьте вывод.

 Мужчины: 
 Лицо: [Имя: Роберт, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Джон, Пол: Мужской, Семейное положение: Женат]
 Лицо: [Имя: Майк, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Бобби, Пол: Мужской, Семейное положение: Холост]

 Женщины: 
 Лицо: [Имя: Лаура, Пол: Женский, Семейное положение: Женат]
 Лицо: [Имя: Диана, Пол: Женский, Семейное положение: Холост]

 Одинокие мужчины: 
 Лицо: [Имя: Роберт, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Майк, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Бобби, Пол: Мужской, Семейное положение: Холост]

 Одиночки или женщины: 
 Лицо: [Имя: Роберт, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Диана, Пол: Женский, Семейное положение: Холост]
 Лицо: [Имя: Майк, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Бобби, Пол: Мужской, Семейное положение: Холост]
 Лицо: [Имя: Лаура, Пол: Женский, Семейное положение: Женат]

Композитный Узор

Составной шаблон используется там, где нам нужно обрабатывать группу объектов аналогичным образом, как один объект. Составной шаблон объединяет объекты в виде древовидной структуры для представления части, а также всей иерархии. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон создает древовидную структуру группы объектов.

Этот шаблон создает класс, содержащий группу собственных объектов. Этот класс предоставляет способы изменить свою группу одинаковых объектов.

Мы демонстрируем использование шаблона Composite на следующем примере, в котором показана иерархия сотрудников организации.

Реализация

У нас есть класс Employee, который действует как класс актера составного паттерна. CompositePatternDemo , наш демонстрационный класс будет использовать класс Employee для добавления иерархии уровня отдела и печати всех сотрудников.

Диаграмма UML составного образца

Шаг 1

Создайте класс Employee, имеющий список объектов Employee .

Employee.java

import java.util.ArrayList;
import java.util.List;

public class Employee {
   private String name;
   private String dept;
   private int salary;
   private List<Employee> subordinates;

   // constructor
   public Employee(String name,String dept, int sal) {
      this.name = name;
      this.dept = dept;
      this.salary = sal;
      subordinates = new ArrayList<Employee>();
   }

   public void add(Employee e) {
      subordinates.add(e);
   }

   public void remove(Employee e) {
      subordinates.remove(e);
   }

   public List<Employee> getSubordinates(){
     return subordinates;
   }

   public String toString(){
      return ("Employee :[ Name : "+ name 
      +", dept : "+ dept + ", salary :"
      + salary+" ]");
   }   
}

Шаг 2

Используйте класс Employee для создания и печати иерархии сотрудников.

CompositePatternDemo.java

public class CompositePatternDemo {
   public static void main(String[] args) {
      Employee CEO = new Employee("John","CEO", 30000);

      Employee headSales = new Employee("Robert","Head Sales", 20000);

      Employee headMarketing = new Employee("Michel","Head Marketing", 20000);

      Employee clerk1 = new Employee("Laura","Marketing", 10000);
      Employee clerk2 = new Employee("Bob","Marketing", 10000);

      Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
      Employee salesExecutive2 = new Employee("Rob","Sales", 10000);

      CEO.add(headSales);
      CEO.add(headMarketing);

      headSales.add(salesExecutive1);
      headSales.add(salesExecutive2);

      headMarketing.add(clerk1);
      headMarketing.add(clerk2);

      //print all employees of the organization
      System.out.println(CEO); 
      for (Employee headEmployee : CEO.getSubordinates()) {
         System.out.println(headEmployee);
         for (Employee employee : headEmployee.getSubordinates()) {
            System.out.println(employee);
         }
      }		
   }
}

Шаг 3

Проверьте вывод.

 Сотрудник: [Имя: Джон, отдел: генеральный директор, зарплата: 30000]
 Сотрудник: [Имя: Роберт, отдел: Начальник отдела продаж, зарплата: 20000]
 Сотрудник: [Имя: Ричард, отдел: Продажи, зарплата: 10000]
 Работник: [Имя: Роб, отдел: Продажи, зарплата: 10000]
 Сотрудник: [Имя: Мишель, отдел: начальник отдела маркетинга, зарплата: 20000]
 Сотрудник: [Имя: Лаура, отдел: Маркетинг, зарплата: 10000]
 Сотрудник: [Имя: Боб, отдел: Маркетинг, зарплата: 10000]

Декоратор Pattern

Шаблон Decorator позволяет добавлять новые функциональные возможности к существующему объекту без изменения его структуры. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон действует как оболочка для существующего класса.

Этот шаблон создает класс декоратора, который оборачивает исходный класс и обеспечивает дополнительную функциональность, сохраняя сигнатуру методов класса без изменений.

Мы демонстрируем использование шаблона Decorator на следующем примере, в котором мы украсим форму некоторым цветом без изменения класса формы.

Реализация

Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . Затем мы создаем абстрактный класс декоратора ShapeDecorator, реализующий интерфейс Shape и имеющий объект Shape в качестве переменной экземпляра.

RedShapeDecorator — это конкретный класс, реализующий ShapeDecorator .

DecoratorPatternDemo , наш демонстрационный класс будет использовать RedShapeDecorator для украшения объектов Shape .

UML Диаграмма Декоратора

Шаг 1

Создать интерфейс.

Shape.java

public interface Shape {
   void draw();
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

Шаг 3

Создайте абстрактный класс декоратора, реализующий интерфейс Shape .

ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;

   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }

   public void draw(){
      decoratedShape.draw();
   }	
}

Шаг 4

Создайте класс декоратора бетона, расширяющий класс ShapeDecorator .

RedShapeDecorator.java

public class RedShapeDecorator extends ShapeDecorator {

   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);		
   }

   @Override
   public void draw() {
      decoratedShape.draw();	       
      setRedBorder(decoratedShape);
   }

   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

Шаг 5

Используйте RedShapeDecorator для украшения объектов Shape .

DecoratorPatternDemo.java

public class DecoratorPatternDemo {
   public static void main(String[] args) {

      Shape circle = new Circle();

      Shape redCircle = new RedShapeDecorator(new Circle());

      Shape redRectangle = new RedShapeDecorator(new Rectangle());
      System.out.println("Circle with normal border");
      circle.draw();

      System.out.println("\nCircle of red border");
      redCircle.draw();

      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}

Шаг 6

Проверьте вывод.

 Круг с нормальной рамкой
 Форма: круг

 Круг красной каймы
 Форма: круг
 Цвет границы: красный

 Прямоугольник с красной каймой
 Форма: прямоугольник
 Цвет границы: красный

Образец фасада

Шаблон фасада скрывает сложности системы и предоставляет клиенту интерфейс, с помощью которого клиент может получить доступ к системе. Этот тип шаблона проектирования подпадает под структурный шаблон, поскольку этот шаблон добавляет интерфейс для выхода из системы, чтобы скрыть ее сложности.

Этот шаблон включает в себя один класс, который предоставляет упрощенные методы, которые требуются клиенту, и делегирует вызовы существующим методам системных классов.

Реализация

Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . Класс фасада ShapeMaker определен как следующий шаг.

Класс ShapeMaker использует конкретные классы для делегирования пользовательских вызовов этим классам. FacadePatternDemo , наш демонстрационный класс будет использовать класс ShapeMaker для отображения результатов.

Схема UML

Шаг 1

Создать интерфейс.

Shape.java

public interface Shape {
   void draw();
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Rectangle::draw()");
   }
}

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Square::draw()");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Circle::draw()");
   }
}

Шаг 3

Создать фасадный класс.

ShapeMaker.java

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;

   public ShapeMaker() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Square();
   }

   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}

Шаг 4

Используйте фасад для рисования различных типов фигур.

FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();

      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();		
   }
}

Шаг 5

Проверьте вывод.

 Круг :: ничья ()
 Прямоугольник :: ничья ()
 Площадь :: ничья ()

Мухи

Шаблон Flyweight в основном используется для уменьшения количества создаваемых объектов, уменьшения занимаемой памяти и увеличения производительности. Этот тип шаблона проектирования подпадает под структурный шаблон, так как этот шаблон обеспечивает способы уменьшения количества объектов, улучшая структуру требуемых объектов приложения.

Шаблон Flyweight пытается повторно использовать уже существующие объекты аналогичного типа, сохраняя их, и создает новый объект, когда соответствующий объект не найден. Мы продемонстрируем эту модель, нарисовав 20 кругов в разных местах, но мы создадим только 5 объектов. Доступно только 5 цветов, поэтому свойство color используется для проверки уже существующих объектов Circle .

Реализация

Мы собираемся создать интерфейс Shape и конкретный класс Circle, реализующий интерфейс Shape . Фабричный класс ShapeFactory определяется как следующий шаг.

ShapeFactory имеет HashMap of Circle, имеющий ключ в качестве цвета объекта Circle . Всякий раз, когда приходит запрос на создание круга определенного цвета для ShapeFactory . ShapeFactory проверяет объект круга в своем HashMap , если объект Circle найден, этот объект возвращается, в противном случае создается новый объект, сохраняется в hashmap для будущего использования и возвращается клиенту.

FlyWeightPatternDemo , наш демонстрационный класс будет использовать ShapeFactory для получения объекта Shape . Он будет передавать информацию ( красный / зеленый / синий / черный / белый ) в ShapeFactory, чтобы получить круг нужного ему цвета.

Диаграмма UML

Шаг 1

Создать интерфейс.

Shape.java

public interface Shape {
   void draw();
}

Шаг 2

Создайте конкретный класс, реализующий тот же интерфейс.

Circle.java

public class Circle implements Shape {
   private String color;
   private int x;
   private int y;
   private int radius;

   public Circle(String color){
      this.color = color;		
   }

   public void setX(int x) {
      this.x = x;
   }

   public void setY(int y) {
      this.y = y;
   }

   public void setRadius(int radius) {
      this.radius = radius;
   }

   @Override
   public void draw() {
      System.out.println("Circle: Draw() [Color : " + color 
         +", x : " + x +", y :" + y +", radius :" + radius);
   }
}

Шаг 3

Создать Фабрику для генерации объекта конкретного класса на основе заданной информации.

ShapeFactory.java

import java.util.HashMap;

public class ShapeFactory {

   // Uncomment the compiler directive line and
   // javac *.java will compile properly.
   // @SuppressWarnings("unchecked")
   private static final HashMap circleMap = new HashMap();

   public static Shape getCircle(String color) {
      Circle circle = (Circle)circleMap.get(color);

      if(circle == null) {
         circle = new Circle(color);
         circleMap.put(color, circle);
         System.out.println("Creating circle of color : " + color);
      }
      return circle;
   }
}

Шаг 4

Используйте Фабрику, чтобы получить объект конкретного класса, передавая информацию, такую ​​как цвет.

FlyweightPatternDemo.java

public class FlyweightPatternDemo {
   private static final String colors[] = 
      { "Red", "Green", "Blue", "White", "Black" };
   public static void main(String[] args) {

      for(int i=0; i < 20; ++i) {
         Circle circle = 
            (Circle)ShapeFactory.getCircle(getRandomColor());
         circle.setX(getRandomX());
         circle.setY(getRandomY());
         circle.setRadius(100);
         circle.draw();
      }
   }
   private static String getRandomColor() {
      return colors[(int)(Math.random()*colors.length)];
   }
   private static int getRandomX() {
      return (int)(Math.random()*100 );
   }
   private static int getRandomY() {
      return (int)(Math.random()*100);
   }
}

Шаг 5

Проверьте вывод.

 Создание круга цвета: черный
 Круг: Draw () [Цвет: черный, x: 36, y: 71, радиус: 100
 Создание круга цвета: зеленый
 Круг: Draw () [Цвет: зеленый, x: 27, y: 27, радиус: 100
 Создание круга цвета: белый
 Круг: Draw () [Цвет: белый, x: 64, y: 10, радиус: 100
 Создание круга цвета: красный
 Круг: Draw () [Цвет: красный, х: 15, у: 44, радиус: 100
 Круг: Draw () [Цвет: зеленый, x: 19, y: 10, радиус: 100
 Круг: Draw () [Цвет: зеленый, х: 94, у: 32, радиус: 100
 Круг: Draw () [Цвет: белый, х: 69, у: 98, радиус: 100
 Создание круга цвета: синий
 Круг: Draw () [Цвет: синий, х: 13, у: 4, радиус: 100
 Круг: Draw () [Цвет: зеленый, x: 21, y: 21, радиус: 100
 Круг: Draw () [Цвет: синий, x: 55, y: 86, радиус: 100
 Круг: Draw () [Цвет: белый, x: 90, y: 70, радиус: 100
 Круг: Draw () [Цвет: зеленый, х: 78, у: 3, радиус: 100
 Круг: Draw () [Цвет: зеленый, х: 64, у: 89, радиус: 100
 Круг: Draw () [Цвет: синий, х: 3, у: 91, радиус: 100
 Круг: Draw () [Цвет: синий, x: 62, y: 82, радиус: 100
 Круг: Draw () [Цвет: зеленый, х: 97, у: 61, радиус: 100
 Круг: Draw () [Цвет: зеленый, x: 86, y: 12, радиус: 100
 Круг: Draw () [Цвет: зеленый, х: 38, у: 93, радиус: 100
 Круг: Draw () [Цвет: красный, х: 76, у: 82, радиус: 100
 Круг: Draw () [Цвет: синий, х: 95, у: 82, радиус: 100

Прокси шаблон

В шаблоне Proxy класс представляет функциональность другого класса. Этот тип шаблона дизайна подпадает под структурный шаблон.

В шаблоне Proxy мы создаем объект, имеющий оригинальный объект, чтобы связать его функциональность с внешним миром.

Реализация

Мы собираемся создать интерфейс Image и конкретные классы, реализующие интерфейс Image . ProxyImage — это прокси-класс, который уменьшает объем памяти, загружаемой объектом RealImage .

ProxyPatternDemo , наш демонстрационный класс будет использовать ProxyImage, чтобы получить объект Image для загрузки и отображения по мере необходимости.

UML-диаграмма прокси-шаблона

Шаг 1

Создать интерфейс.

Image.java

public interface Image {
   void display();
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

RealImage.java

public class RealImage implements Image {

   private String fileName;

   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }

   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }

   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

ProxyImage.java

public class ProxyImage implements Image{

   private RealImage realImage;
   private String fileName;

   public ProxyImage(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}

Шаг 3

Используйте ProxyImage, чтобы получить объект класса RealImage при необходимости.

ProxyPatternDemo.java

public class ProxyPatternDemo {
	
   public static void main(String[] args) {
      Image image = new ProxyImage("test_10mb.jpg");

      //image will be loaded from disk
      image.display(); 
      System.out.println("");
      //image will not be loaded from disk
      image.display(); 	
   }
}

Шаг 4

Проверьте вывод.

 Загрузка test_10mb.jpg
 Отображение test_10mb.jpg

 Отображение test_10mb.jpg

Схема цепочки ответственности

Как следует из названия, шаблон цепочки ответственности создает цепочку объектов-получателей для запроса. Этот шаблон разъединяет отправителя и получателя запроса в зависимости от типа запроса. Эта модель подпадает под поведенческие модели.

В этом шаблоне обычно каждый получатель содержит ссылку на другой получатель. Если один объект не может обработать запрос, он передает его следующему получателю и так далее.

Реализация

Мы создали абстрактный класс AbstractLogger с уровнем ведения журнала. Затем мы создали три типа регистраторов, расширяющих AbstractLogger . Каждый регистратор проверяет уровень сообщения до своего уровня и печатает соответственно, иначе не печатает и не передает сообщение следующему регистратору.

UML Diagram Chain of Responsibility Pattern

Шаг 1

Создайте абстрактный класс логгера.

AbstractLogger.java

public abstract class AbstractLogger {
   public static int INFO = 1;
   public static int DEBUG = 2;
   public static int ERROR = 3;

   protected int level;

   //next element in chain or responsibility
   protected AbstractLogger nextLogger;

   public void setNextLogger(AbstractLogger nextLogger){
      this.nextLogger = nextLogger;
   }

   public void logMessage(int level, String message){
      if(this.level <= level){
         write(message);
      }
      if(nextLogger !=null){
         nextLogger.logMessage(level, message);
      }
   }

   abstract protected void write(String message);
	
}

Шаг 2

Создавайте конкретные классы, расширяющие регистратор.

ConsoleLogger.java

public class ConsoleLogger extends AbstractLogger {

   public ConsoleLogger(int level){
      this.level = level;
   }

   @Override
   protected void write(String message) {		
      System.out.println("Standard Console::Logger: " + message);
   }
}

ErrorLogger.java

public class ErrorLogger extends AbstractLogger {

   public ErrorLogger(int level){
      this.level = level;
   }

   @Override
   protected void write(String message) {		
      System.out.println("Error Console::Logger: " + message);
   }
}

FileLogger.java

public class FileLogger extends AbstractLogger {

   public FileLogger(int level){
      this.level = level;
   }

   @Override
   protected void write(String message) {		
      System.out.println("File::Logger: " + message);
   }
}

Шаг 3

Создавайте разные типы регистраторов. Назначьте им уровни ошибок и установите следующий регистратор в каждом регистраторе. Следующий регистратор в каждом регистраторе представляет часть цепочки.

ChainPatternDemo.java

public class ChainPatternDemo {
	
   private static AbstractLogger getChainOfLoggers(){

      AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
      AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
      AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);

      errorLogger.setNextLogger(fileLogger);
      fileLogger.setNextLogger(consoleLogger);

      return errorLogger;	
   }

   public static void main(String[] args) {
      AbstractLogger loggerChain = getChainOfLoggers();

      loggerChain.logMessage(AbstractLogger.INFO, 
         "This is an information.");

      loggerChain.logMessage(AbstractLogger.DEBUG, 
         "This is an debug level information.");

      loggerChain.logMessage(AbstractLogger.ERROR, 
         "This is an error information.");
   }
}

Шаг 4

Проверьте вывод.

 Стандартная консоль :: Logger: это информация.
 File :: Logger: это информация об уровне отладки.
 Standard Console :: Logger: это информация об уровне отладки.
 Error Console :: Logger: это информация об ошибке.
 File :: Logger: это информация об ошибке.
 Стандартная консоль :: Logger: это информация об ошибке.

Шаблон команды

Шаблон команды — это шаблон проектирования, управляемый данными, который подпадает под категорию поведенческих шаблонов. Запрос оборачивается под объектом как команда и передается объекту invoker. Объект Invoker ищет соответствующий объект, который может обработать эту команду и передать команду соответствующему объекту, и этот объект выполняет команду.

Реализация

Мы создали интерфейс Order, который действует как команда. Мы создали класс Stock, который действует как запрос. У нас есть конкретные командные классы BuyStock и SellStock, реализующие интерфейс Order, который будет выполнять фактическую обработку команд. Создается класс Broker, который действует как объект invoker. Он может принимать заказы и размещать заказы.

Объект- посредник использует шаблон команды, чтобы определить, какой объект будет выполнять какую команду в зависимости от типа команды. CommandPatternDemo , наш демонстрационный класс будет использовать класс Broker для демонстрации шаблона команды.

UML Diagram

Шаг 1

Создать командный интерфейс.

Order.java

public interface Order {
   void execute();
}

Шаг 2

Создайте класс запроса.

Stock.java

public class Stock {
	
   private String name = "ABC";
   private int quantity = 10;

   public void buy(){
      System.out.println("Stock [ Name: "+name+", 
         Quantity: " + quantity +" ] bought");
   }
   public void sell(){
      System.out.println("Stock [ Name: "+name+", 
         Quantity: " + quantity +" ] sold");
   }
}

Шаг 3

Создать конкретные классы, реализующие интерфейс Order .

BuyStock.java

public class BuyStock implements Order {
   private Stock abcStock;

   public BuyStock(Stock abcStock){
      this.abcStock = abcStock;
   }

   public void execute() {
      abcStock.buy();
   }
}

SellStock.java

public class SellStock implements Order {
   private Stock abcStock;

   public SellStock(Stock abcStock){
      this.abcStock = abcStock;
   }

   public void execute() {
      abcStock.sell();
   }
}

Шаг 4

Создать команду invoker class.

Broker.java

import java.util.ArrayList;
import java.util.List;

   public class Broker {
   private List<Order> orderList = new ArrayList<Order>(); 

   public void takeOrder(Order order){
      orderList.add(order);		
   }

   public void placeOrders(){
      for (Order order : orderList) {
         order.execute();
      }
      orderList.clear();
   }
}

Шаг 5

Используйте класс Broker для принятия и выполнения команд.

CommandPatternDemo.java

public class CommandPatternDemo {
   public static void main(String[] args) {
      Stock abcStock = new Stock();

      BuyStock buyStockOrder = new BuyStock(abcStock);
      SellStock sellStockOrder = new SellStock(abcStock);

      Broker broker = new Broker();
      broker.takeOrder(buyStockOrder);
      broker.takeOrder(sellStockOrder);

      broker.placeOrders();
   }
}

Шаг 6

Проверьте вывод.

 Акции [Название: ABC, Количество: 10] купили
 Акции [Наименование: ABC, Количество: 10] продано

Образец переводчика

Шаблон интерпретатора предоставляет способ оценить грамматику языка или выражение. Этот тип паттернов подпадает под поведенческие паттерны. Этот шаблон включает в себя реализацию интерфейса выражений, который говорит интерпретировать определенный контекст. Этот шаблон используется при разборе SQL, обработчике символов и т. Д.

Реализация

Мы собираемся создать интерфейс Expression и конкретные классы, реализующие интерфейс Expression . Определен класс TerminalExpression, который выступает в качестве основного интерпретатора рассматриваемого контекста. Другие классы OrExpression , AndExpression используются для создания комбинационных выражений.

InterpreterPatternDemo , наш демонстрационный класс будет использовать класс Expression для создания правил и демонстрации разбора выражений.

UML Диаграмма интерпретатора

Шаг 1

Создайте интерфейс выражения.

Expression.java

public interface Expression {
   public boolean interpret(String context);
}

Шаг 2

Создайте конкретные классы, реализующие вышеуказанный интерфейс.

TerminalExpression.java

public class TerminalExpression implements Expression {
	
   private String data;

   public TerminalExpression(String data){
      this.data = data; 
   }

   @Override
   public boolean interpret(String context) {
      if(context.contains(data)){
         return true;
      }
      return false;
   }
}

OrExpression.java

public class OrExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public OrExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) || expr2.interpret(context);
   }
}

AndExpression.java

public class AndExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public AndExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) && expr2.interpret(context);
   }
}

Шаг 3

InterpreterPatternDemo использует класс Expression для создания правил и последующего их анализа.

InterpreterPatternDemo.java

public class InterpreterPatternDemo {

   //Rule: Robert and John are male
   public static Expression getMaleExpression(){
      Expression robert = new TerminalExpression("Robert");
      Expression john = new TerminalExpression("John");
      return new OrExpression(robert, john);		
   }

   //Rule: Julie is a married women
   public static Expression getMarriedWomanExpression(){
      Expression julie = new TerminalExpression("Julie");
      Expression married = new TerminalExpression("Married");
      return new AndExpression(julie, married);		
   }

   public static void main(String[] args) {
      Expression isMale = getMaleExpression();
      Expression isMarriedWoman = getMarriedWomanExpression();

      System.out.println("John is male? " + isMale.interpret("John"));
      System.out.println("Julie is a married women? " 
      + isMarriedWoman.interpret("Married Julie"));
   }
}

Шаг 4

Проверьте вывод.

 Джон мужчина?  правда
 Джули это замужняя женщина?  правда

Шаблон итератора

Шаблон итератора — это очень часто используемый шаблон проектирования в среде программирования Java и .Net. Этот шаблон используется для последовательного доступа к элементам объекта коллекции без необходимости знать его базовое представление.

Шаблон итератора подпадает под категорию поведенческих шаблонов.

Реализация

Мы собираемся создать интерфейс Iterator, который описывает метод навигации, и интерфейс Container, который перезапускает итератор. Конкретные классы, реализующие интерфейс Контейнера, будут ответственны за реализацию интерфейса Итератора и его использование.

IteratorPatternDemo , наш демонстрационный класс будет использовать NamesRepository , конкретную реализацию класса для печати Имен, хранящихся в виде коллекции в NamesRepository .

Шаблон итератора UML-диаграмма

Шаг 1

Создавайте интерфейсы.

Iterator.java

public interface Iterator {
   public boolean hasNext();
   public Object next();
}

Container.java

public interface Container {
   public Iterator getIterator();
}

Шаг 2

Создайте конкретный класс, реализующий интерфейс Контейнера . Этот класс имеет внутренний класс NameIterator, реализующий интерфейс Iterator .

NameRepository.java

public class NameRepository implements Container {
   public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};

   @Override
   public Iterator getIterator() {
      return new NameIterator();
   }

   private class NameIterator implements Iterator {

      int index;

      @Override
      public boolean hasNext() {
         if(index < names.length){
            return true;
         }
         return false;
      }

      @Override
      public Object next() {
         if(this.hasNext()){
            return names[index++];
         }
         return null;
      }		
   }
}

Шаг 3

Используйте NameRepository, чтобы получить итератор и вывести имена.

IteratorPatternDemo.java

public class IteratorPatternDemo {
	
   public static void main(String[] args) {
      NameRepository namesRepository = new NameRepository();

      for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
         String name = (String)iter.next();
         System.out.println("Name : " + name);
      } 	
   }
}

Шаг 4

Проверьте вывод.

 Имя: Роберт
 Имя: Джон
 Имя: Джули
 Имя: Лора

Образец посредника

Шаблон посредника используется для уменьшения сложности связи между несколькими объектами или классами. Этот шаблон предоставляет класс-посредник, который обычно обрабатывает все взаимодействия между различными классами и поддерживает простоту сопровождения кода за счет слабой связи. Паттерн медиатора подпадает под категорию паттернов поведения.

Реализация

Мы демонстрируем шаблон посредника на примере чата, где несколько пользователей могут отправлять сообщения в чаты, и чаты обязаны показывать сообщения всем пользователям. Мы создали два класса ChatRoom и User . Пользовательские объекты будут использовать метод ChatRoom, чтобы делиться своими сообщениями.

MediatorPatternDemo , наш демонстрационный класс будет использовать объекты User, чтобы показать связь между ними.

Диаграмма посредника UML

Шаг 1

Создать класс-посредник.

ChatRoom.java

import java.util.Date;

public class ChatRoom {
   public static void showMessage(User user, String message){
      System.out.println(new Date().toString()
         + " [" + user.getName() +"] : " + message);
   }
}

Шаг 2

Создать класс пользователя

User.java

public class User {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public User(String name){
      this.name  = name;
   }

   public void sendMessage(String message){
      ChatRoom.showMessage(this,message);
   }
}

Шаг 3

Используйте объект User, чтобы показать связь между ними.

MediatorPatternDemo.java

public class MediatorPatternDemo {
   public static void main(String[] args) {
      User robert = new User("Robert");
      User john = new User("John");

      robert.sendMessage("Hi! John!");
      john.sendMessage("Hello! Robert!");
   }
}

Шаг 4

Проверьте вывод.

 Чт 31 января 16:05:46 IST 2013 [Роберт]: Привет!  Джон!
 Чт 31 января 16:05:46 IST 2013 [Джон]: Привет!  Роберт!

Памятная картина

Шаблон Memento используется для уменьшения того, где мы хотим восстановить состояние объекта до предыдущего состояния. Шаблон Memento подпадает под категорию поведенческих шаблонов.

Реализация

Шаблон Memento использует три актерских класса. Памятка содержит состояние объекта, который будет восстановлен. Originator создает и сохраняет состояния в объектах Memento и объекте смотрителя, который отвечает за восстановление состояния объекта из Memento. Мы создали классы Memento , Originator и CareTaker .

MementoPatternDemo , наш демонстрационный класс будет использовать объекты CareTaker и Originator, чтобы показать восстановление состояний объекта.

UML-диаграмма Memento Pattern

Шаг 1

Создать класс Memento.

Memento.java

public class Memento {
   private String state;

   public Memento(String state){
      this.state = state;
   }

   public String getState(){
      return state;
   }	
}

Шаг 2

Создать класс Originator

Originator.java

public class Originator {
   private String state;

   public void setState(String state){
      this.state = state;
   }

   public String getState(){
      return state;
   }

   public Memento saveStateToMemento(){
      return new Memento(state);
   }

   public void getStateFromMemento(Memento Memento){
      state = memento.getState();
   }
}

Шаг 3

Создать класс CareTaker

CareTaker.java

import java.util.ArrayList;
import java.util.List;

public class CareTaker {
   private List<Memento> mementoList = new ArrayList<Memento>();

   public void add(Memento state){
      mementoList.add(state);
   }

   public Memento get(int index){
      return mementoList.get(index);
   }
}

Шаг 4

Используйте объекты CareTaker и Originator .

MementoPatternDemo.java

public class MementoPatternDemo {
   public static void main(String[] args) {
      Originator originator = new Originator();
      CareTaker careTaker = new CareTaker();
      originator.setState("State #1");
      originator.setState("State #2");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #3");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #4");

      System.out.println("Current State: " + originator.getState());		
      originator.getStateFromMemento(careTaker.get(0));
      System.out.println("First saved State: " + originator.getState());
      originator.getStateFromMemento(careTaker.get(1));
      System.out.println("Second saved State: " + originator.getState());
   }
}

Шаг 5

Проверьте вывод.

 Текущее состояние: состояние № 4
 Первое сохраненное состояние: состояние # 2
 Второе сохраненное состояние: состояние № 3

Шаблон наблюдателя

Шаблон наблюдателя используется, когда между объектами существует отношение один ко многим, например, если один объект изменен, его зависимые объекты должны уведомляться автоматически. Модель наблюдателя подпадает под категорию поведенческих моделей.

Реализация

Шаблон Observer использует три класса актеров. Субъект, Наблюдатель и Клиент. Subject — объект, имеющий методы для присоединения и отмены присоединения наблюдателей к клиентскому объекту. Мы создали классы Subject , абстрактный класс Observer и конкретные классы, расширяющие абстрактный класс Observer .

ObserverPatternDemo , наш демонстрационный класс будет использовать объекты Subject и конкретный класс, чтобы показать образец наблюдателя в действии.

UML Диаграмма Наблюдателя

Шаг 1

Создать предметный класс.

Subject.java

import java.util.ArrayList;
import java.util.List;

public class Subject {
	
   private List<Observer> observers 
      = new ArrayList<Observer>();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
      observers.add(observer);		
   }

   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   } 	
}

Шаг 2

Создать класс Observer.

Observer.java

public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Шаг 3

Создать конкретные классы наблюдателей

BinaryObserver.java

public class BinaryObserver extends Observer{

   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Binary String: " 
      + Integer.toBinaryString( subject.getState() ) ); 
   }
}

OctalObserver.java

public class OctalObserver extends Observer{

   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
     System.out.println( "Octal String: " 
     + Integer.toOctalString( subject.getState() ) ); 
   }
}

HexaObserver.java

public class HexaObserver extends Observer{

   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Hex String: " 
      + Integer.toHexString( subject.getState() ).toUpperCase() ); 
   }
}

Шаг 4

Используйте предметные и конкретные объекты наблюдения.

ObserverPatternDemo.java

public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();

      new HexaObserver(subject);
      new OctalObserver(subject);
      new BinaryObserver(subject);

      System.out.println("First state change: 15");	
      subject.setState(15);
      System.out.println("Second state change: 10");	
      subject.setState(10);
   }
}

Шаг 5

Проверьте вывод.

 Первое изменение состояния: 15
 Шестнадцатеричная строка: F
 Восьмеричная строка: 17
 Двоичная строка: 1111
 Второе изменение состояния: 10
 Шестнадцатеричная строка: A
 Восьмеричная строка: 12
 Двоичная строка: 1010

Государственный Образец

В шаблоне State поведение класса изменяется в зависимости от его состояния. Этот тип шаблона проектирования подпадает под модель поведения.

В паттерне State мы создаем объекты, которые представляют различные состояния, и объект контекста, поведение которого меняется по мере изменения его объекта состояния.

Реализация

Мы собираемся создать интерфейс State, определяющий действие и конкретные классы состояний, реализующие интерфейс State . Контекст — это класс, который несет состояние.

StaePatternDemo , наш демонстрационный класс будет использовать объекты Context и состояния для демонстрации изменений в поведении Context в зависимости от типа состояния, в котором он находится.

UML-диаграмма состояний

Шаг 1

Создать интерфейс.

Image.java

public interface State {
   public void doAction(Context context);
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

StartState.java

public class StartState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);	
   }

   public String toString(){
      return "Start State";
   }
}

StopState.java

public class StopState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this);	
   }

   public String toString(){
      return "Stop State";
   }
}

Шаг 3

Создать контекстный класс.

Context.java

public class Context {
   private State state;

   public Context(){
      state = null;
   }

   public void setState(State state){
      this.state = state;		
   }

   public State getState(){
      return state;
   }
}

Шаг 4

Используйте контекст, чтобы увидеть изменения в поведении при изменении состояния.

StatePatternDemo.java

public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      StartState startState = new StartState();
      startState.doAction(context);

      System.out.println(context.getState().toString());

      StopState stopState = new StopState();
      stopState.doAction(context);

      System.out.println(context.getState().toString());
   }
}

Шаг 5

Проверьте вывод.

 Игрок находится в начальном состоянии
 Начальное состояние
 Игрок находится в состоянии остановки
 Stop State

Шаблон нулевого объекта

В шаблоне Null Object пустой объект заменяет проверку экземпляра NULL-объекта. Вместо того, чтобы ставить проверку if для нулевого значения, Null Object отражает отношение бездействия. Такой нулевой объект также можно использовать для обеспечения поведения по умолчанию в случае, если данные недоступны.

В паттерне Null Object мы создаем абстрактный класс, определяющий различные операции, которые нужно выполнить, конкретизируем классы, расширяющие этот класс, и класс нулевого объекта, обеспечивающий реализацию этого класса, ничего не делающего, и он будет использоваться, по-видимому, там, где нам нужно проверить нулевое значение.

Реализация

Мы собираемся создать абстрактный класс AbstractCustomer, определяющий операции, здесь имя клиента и конкретные классы, расширяющие класс AbstractCustomer . Фабричный класс CustomerFactory создается для возврата объектов RealCustomer или NullCustomer на основе переданного ему имени клиента.

NullPatternDemo , наш демонстрационный класс будет использовать CustomerFactory для демонстрации использования шаблона Null Object.

UML-диаграмма с нулевым объектом

Шаг 1

Создайте абстрактный класс.

AbstractCustomer.java

public abstract class AbstractCustomer {
   protected String name;
   public abstract boolean isNil();
   public abstract String getName();
}

Шаг 2

Создайте конкретные классы, расширяющие вышеуказанный класс.

RealCustomer.java

public class RealCustomer extends AbstractCustomer {

   public RealCustomer(String name) {
      this.name = name;		
   }
   
   @Override
   public String getName() {
      return name;
   }
   
   @Override
   public boolean isNil() {
      return false;
   }
}

NullCustomer.java

public class NullCustomer extends AbstractCustomer {

   @Override
   public String getName() {
      return "Not Available in Customer Database";
   }

   @Override
   public boolean isNil() {
      return true;
   }
}

Шаг 3

Создать класс CustomerFactory .

CustomerFactory.java

public class CustomerFactory {
	
   public static final String[] names = {"Rob", "Joe", "Julie"};

   public static AbstractCustomer getCustomer(String name){
      for (int i = 0; i < names.length; i++) {
         if (names[i].equalsIgnoreCase(name)){
            return new RealCustomer(name);
         }
      }
      return new NullCustomer();
   }
}

Шаг 4

Используйте CustomerFactory для получения объектов RealCustomer или NullCustomer на основе имени клиента, переданного ему.

NullPatternDemo.java

public class NullPatternDemo {
   public static void main(String[] args) {

      AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
      AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
      AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
      AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");

      System.out.println("Customers");
      System.out.println(customer1.getName());
      System.out.println(customer2.getName());
      System.out.println(customer3.getName());
      System.out.println(customer4.getName());
   }
}

Шаг 5

Проверьте вывод.

 Клиенты
 обкрадывать
 Недоступно в базе данных клиентов
 Julie
 Недоступно в базе данных клиентов

Стратегия

В паттерне Стратегия поведение класса или его алгоритм могут быть изменены во время выполнения. Этот тип шаблона проектирования подпадает под модель поведения.

В паттерне «Стратегия» мы создаем объекты, представляющие различные стратегии, и объект контекста, поведение которого меняется в зависимости от объекта стратегии. Объект стратегии изменяет алгоритм выполнения объекта контекста.

Реализация

Мы собираемся создать интерфейс стратегии, определяющий действие и конкретные классы стратегии, реализующие интерфейс стратегии . Контекст — это класс, который использует стратегию.

StrategyPatternDemo , наш демонстрационный класс будет использовать объекты Context и стратегии для демонстрации изменений в поведении Context в зависимости от стратегии, которую он развертывает или использует.

Шаблон стратегии UML Диаграмма

Шаг 1

Создать интерфейс.

Strategy.java

public interface Strategy {
   public int doOperation(int num1, int num2);
}

Шаг 2

Создайте конкретные классы, реализующие тот же интерфейс.

OperationAdd.java

public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 + num2;
   }
}

OperationSubstract.java

public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}

OperationMultiply.java

public class OperationMultiply implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 * num2;
   }
}

Шаг 3

Создать контекстный класс.

Context.java

public class Context {
   private Strategy strategy;

   public Context(Strategy strategy){
      this.strategy = strategy;
   }

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

Шаг 4

Используйте контекст, чтобы увидеть изменения в поведении, когда он меняет свою стратегию .

StatePatternDemo.java

public class StrategyPatternDemo {
   public static void main(String[] args) {
      Context context = new Context(new OperationAdd());		
      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationSubstract());		
      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationMultiply());		
      System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}

Шаг 5

Проверьте вывод.

 10 + 5 = 15
 10 - 5 = 5
 10 * 5 = 50

Шаблон

В шаблоне Шаблон абстрактный класс предоставляет определенный способ (ы) / шаблон (ы) для выполнения своих методов. Его подклассы могут переопределять реализации метода по мере необходимости, но вызов должен быть таким же, как определено абстрактным классом. Этот шаблон относится к категории шаблонов поведения.

Реализация

Мы собираемся создать абстрактный класс Game, определяющий операции с методом шаблона, установленным как final, чтобы его нельзя было переопределить. Крикет и футбол — это конкретные классы, расширяющие возможности Game и переопределяющие ее методы.

TemplatePatternDemo , наш демонстрационный класс будет использовать Game, чтобы продемонстрировать использование шаблона.

Шаблон Шаблон UML Диаграмма

Шаг 1

Создайте абстрактный класс с методом шаблона, являющимся окончательным.

Game.java

public abstract class Game {
   abstract void initialize();
   abstract void startPlay();
   abstract void endPlay();

   //template method
   public final void play(){

      //initialize the game
      initialize();

      //start game
      startPlay();

      //end game
      endPlay();
   }
}

Шаг 2

Создайте конкретные классы, расширяющие вышеуказанный класс.

Cricket.java

public class Cricket extends Game {

   @Override
   void endPlay() {
      System.out.println("Cricket Game Finished!");
   }

   @Override
   void initialize() {
      System.out.println("Cricket Game Initialized! Start playing.");
   }

   @Override
   void startPlay() {
      System.out.println("Cricket Game Started. Enjoy the game!");
   }
}

Football.java

public class Football extends Game {
   @Override
   void endPlay() {
      System.out.println("Football Game Finished!");
   }

   @Override
   void initialize() {
      System.out.println("Football Game Initialized! Start playing.");
   }

   @Override
   void startPlay() {
      System.out.println("Football Game Started. Enjoy the game!");
   }
}

Шаг 3

Используйте шаблонный метод Game play (), чтобы продемонстрировать определенный способ игры.

TemplatePatternDemo.java

public class TemplatePatternDemo {
   public static void main(String[] args) {

      Game game = new Cricket();
      game.play();
      System.out.println();
      game = new Football();
      game.play();		
   }
}

Шаг 4

Проверьте вывод.

 Игра в крикет инициализирована!  Начни играть.
 Игра в крикет началась.  Наслаждайся игрой!
 Игра в крикет завершена!

 Футбольная игра инициализирована!  Начни играть.
 Футбольный матч начался.  Наслаждайся игрой!
 Футбол закончен!

Шаблон посетителя

В шаблоне Visitor мы используем класс посетителя, который изменяет алгоритм выполнения класса элемента. Таким образом, алгоритм выполнения элемента может варьироваться в зависимости от посетителя. Этот шаблон относится к категории шаблонов поведения. Согласно шаблону объект-элемент должен принимать объект-посетитель, чтобы объект-посетитель выполнял операцию над объектом-элементом.

Реализация

Мы собираемся создать интерфейс ComputerPart, определяющий приемную операцию. Клавиатура , мышь , монитор и компьютер — это конкретные классы, реализующие интерфейс ComputerPart . Мы определим другой интерфейс ComputerPartVisitor, который будет определять операции класса посетителя. Компьютер использует конкретного посетителя для выполнения соответствующих действий.

VisitorPatternDemo , наш демонстрационный класс будет использовать классы Computer , ComputerPartVisitor для демонстрации использования шаблона посетителя.

Шаблон UML для посетителей

Шаг 1

Определите интерфейс для представления элемента.

ComputerPart.java

public interface class ComputerPart {
   public void accept(ComputerPartVisitor computerPartVisitor);
}

Шаг 2

Создайте конкретные классы, расширяющие вышеуказанный класс.

Keyboard.java

public class Keyboard  implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Monitor.java

public class Monitor  implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Mouse.java

public class Mouse  implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Computer.java

public class Computer implements ComputerPart {
	
   ComputerPart[] parts;

   public Computer(){
      parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};		
   } 


   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      for (int i = 0; i < parts.length; i++) {
         parts[i].accept(computerPartVisitor);
      }
      computerPartVisitor.visit(this);
   }
}

Шаг 3

Определите интерфейс для представления посетителя.

ComputerPartVisitor.java

public interface ComputerPartVisitor {
	public void visit(Computer computer);
	public void visit(Mouse mouse);
	public void visit(Keyboard keyboard);
	public void visit(Monitor monitor);
}

Шаг 4

Создайте конкретного посетителя, реализующего вышеуказанный класс.

ComputerPartDisplayVisitor.java

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

   @Override
   public void visit(Computer computer) {
      System.out.println("Displaying Computer.");
   }

   @Override
   public void visit(Mouse mouse) {
      System.out.println("Displaying Mouse.");
   }

   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("Displaying Keyboard.");
   }

   @Override
   public void visit(Monitor monitor) {
      System.out.println("Displaying Monitor.");
   }
}

Шаг 5

Используйте ComputerPartDisplayVisitor для отображения частей компьютера .

VisitorPatternDemo.java

public class VisitorPatternDemo {
   public static void main(String[] args) {

      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

Шаг 6

Проверьте вывод.

 Отображение мыши.
 Отображение клавиатуры.
 Отображение монитора.
 Дисплей Компьютер.

MVC Pattern

Образец MVC расшифровывается как Pattern-View-Controller Pattern. Этот шаблон используется для разделения проблем приложения.

  • Модель — Модель представляет объект или JAVA POJO, несущий данные. Он также может иметь логику для обновления контроллера, если его данные изменяются.

  • Представление — представление представляет собой визуализацию данных, содержащихся в модели.

  • Контроллер — Контроллер действует как на модель, так и на вид. Он контролирует поток данных в объект модели и обновляет представление при каждом изменении данных. Это держит View и Model отдельно.

Модель — Модель представляет объект или JAVA POJO, несущий данные. Он также может иметь логику для обновления контроллера, если его данные изменяются.

Представление — представление представляет собой визуализацию данных, содержащихся в модели.

Контроллер — Контроллер действует как на модель, так и на вид. Он контролирует поток данных в объект модели и обновляет представление при каждом изменении данных. Это держит View и Model отдельно.

Реализация

Мы собираемся создать объект Student, выступающий в качестве модели. StudentView будет классом представления, который может печатать данные ученика на консоли, а StudentController является классом контроллера, ответственным за хранение данных в объекте Student и, соответственно, за обновление представления StudentView .

MVCPatternDemo , наш демонстрационный класс будет использовать StudentController для демонстрации использования шаблона MVC.

UML-диаграмма MVC Pattern

Шаг 1

Создать модель.

Student.java

public class Student {
   private String rollNo;
   private String name;
   public String getRollNo() {
      return rollNo;
   }
   public void setRollNo(String rollNo) {
      this.rollNo = rollNo;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}

Шаг 2

Создать вид.

StudentView.java

public class StudentView {
   public void printStudentDetails(String studentName, String studentRollNo){
      System.out.println("Student: ");
      System.out.println("Name: " + studentName);
      System.out.println("Roll No: " + studentRollNo);
   }
}

Шаг 3

Создать контроллер.

StudentController.java

public class StudentController {
   private Student model;
   private StudentView view;

   public StudentController(Student model, StudentView view){
      this.model = model;
      this.view = view;
   }

   public void setStudentName(String name){
      model.setName(name);		
   }

   public String getStudentName(){
      return model.getName();		
   }

   public void setStudentRollNo(String rollNo){
      model.setRollNo(rollNo);		
   }

   public String getStudentRollNo(){
      return model.getRollNo();		
   }

   public void updateView(){				
      view.printStudentDetails(model.getName(), model.getRollNo());
   }	
}

Шаг 4

Используйте методы StudentController, чтобы продемонстрировать использование шаблона проектирования MVC.

MVCPatternDemo.java

public class MVCPatternDemo {
   public static void main(String[] args) {

      //fetch student record based on his roll no from the database
      Student model  = retriveStudentFromDatabase();

      //Create a view : to write student details on console
      StudentView view = new StudentView();

      StudentController controller = new StudentController(model, view);

      controller.updateView();

      //update model data
      controller.setStudentName("John");

      controller.updateView();
   }

   private static Student retriveStudentFromDatabase(){
      Student student = new Student();
      student.setName("Robert");
      student.setRollNo("10");
      return student;
   }
}

Шаг 5

Проверьте вывод.

 Ученик: 
 Имя: Роберт
 Рулон № 10
 Ученик: 
 Имя: Джули
 Рулон № 10

Шаблон бизнес-делегата

Шаблон бизнес-делегата используется для разделения уровня представления и уровня бизнеса. Он в основном используется для сведения функциональности связи или удаленного поиска к коду бизнес-уровня в коде уровня презентации. На бизнес-уровне у нас есть следующие объекты.

  • Код уровня клиента — представления может быть кодом JSP, сервлетом или кодом Java.

  • Business Delegate — Единый класс точки входа для клиентских объектов, обеспечивающий доступ к методам Business Service.

  • Сервис LookUp — объект службы Lookup отвечает за получение относительной бизнес-реализации и предоставление доступа бизнес-объекта к объекту бизнес-делегата.

  • Бизнес Сервис — Интерфейс Бизнес Сервиса. Конкретные классы реализуют этот бизнес-сервис для обеспечения реальной логики реализации бизнеса.

Код уровня клиента — представления может быть кодом JSP, сервлетом или кодом Java.

Business Delegate — Единый класс точки входа для клиентских объектов, обеспечивающий доступ к методам Business Service.

Сервис LookUp — объект службы Lookup отвечает за получение относительной бизнес-реализации и предоставление доступа бизнес-объекта к объекту бизнес-делегата.

Бизнес Сервис — Интерфейс Бизнес Сервиса. Конкретные классы реализуют этот бизнес-сервис для обеспечения реальной логики реализации бизнеса.

Реализация

Мы собираемся создать Client , BusinessDelegate , BusinessService , LookUpService , JMSService и EJBService, представляющие различные объекты шаблона Business Delegate.

BusinessDelegatePatternDemo , наш демонстрационный класс будет использовать BusinessDelegate и Client для демонстрации использования шаблона Business Delegate.

Диаграмма UML бизнес-делегата

Шаг 1

Создать интерфейс BusinessService.

BusinessService.java

public interface BusinessService {
   public void doProcessing();
}

Шаг 2

Создать конкретные классы обслуживания.

EJBService.java

public class EJBService implements BusinessService {

   @Override
   public void doProcessing() {
      System.out.println("Processing task by invoking EJB Service");
   }
}

JMSService.java

public class JMSService implements BusinessService {

   @Override
   public void doProcessing() {
      System.out.println("Processing task by invoking JMS Service");
   }
}

Шаг 3

Создать службу бизнес-поиска.

BusinessLookUp.java

public class BusinessLookUp {
   public BusinessService getBusinessService(String serviceType){
      if(serviceType.equalsIgnoreCase("EJB")){
         return new EJBService();
      }else {
         return new JMSService();
      }
   }
}

Шаг 4

Создать бизнес-делегата.

BusinessLookUp.java

public class BusinessDelegate {
   private BusinessLookUp lookupService = new BusinessLookUp();
   private BusinessService businessService;
   private String serviceType;

   public void setServiceType(String serviceType){
      this.serviceType = serviceType;
   }

   public void doTask(){
      businessService = lookupService.getBusinessService(serviceType);
      businessService.doProcessing();		
   }
}

Шаг 5

Создать клиента.

Student.java

public class Client {
	
   BusinessDelegate businessService;

   public Client(BusinessDelegate businessService){
      this.businessService  = businessService;
   }

   public void doTask(){		
      businessService.doTask();
   }
}

Шаг 6

Используйте классы BusinessDelegate и Client для демонстрации шаблона Business Delegate.

BusinessDelegatePatternDemo.java

public class BusinessDelegatePatternDemo {
	
   public static void main(String[] args) {

      BusinessDelegate businessDelegate = new BusinessDelegate();
      businessDelegate.setServiceType("EJB");

      Client client = new Client(businessDelegate);
      client.doTask();

      businessDelegate.setServiceType("JMS");
      client.doTask();
   }
}

Шаг 7

Проверьте вывод.

 Обработка задачи путем вызова EJB Service
 Обработка задачи путем вызова службы JMS

Составной шаблон сущности

Шаблон составного объекта используется в механизме персистентности EJB. Составная сущность — это EJB-сущностный бин, представляющий граф объектов. Когда составной объект обновляется, внутренне-зависимые объекты-объекты автоматически обновляются как управляемые компонентом EJB-компонента. Ниже приведены участники в компонентном компоненте.

  • Составной объект — это первичный объектный компонент. Он может быть крупнозернистым или содержать крупнозернистый объект для использования в постоянных целях.

  • Крупнозернистый объект -Этот объект содержит зависимые объекты. Он имеет свой жизненный цикл, а также управляет жизненным циклом зависимых объектов.

  • Зависимый объект — Зависимый объект — это объект, который зависит от крупнозернистого объекта в течение его жизненного цикла.

  • Стратегии — Стратегия представляет, как реализовать составную сущность.

Составной объект — это первичный объектный компонент. Он может быть крупнозернистым или содержать крупнозернистый объект для использования в постоянных целях.

Крупнозернистый объект -Этот объект содержит зависимые объекты. Он имеет свой жизненный цикл, а также управляет жизненным циклом зависимых объектов.

Зависимый объект — Зависимый объект — это объект, который зависит от крупнозернистого объекта в течение его жизненного цикла.

Стратегии — Стратегия представляет, как реализовать составную сущность.

Реализация

Мы собираемся создать объект CompositeEntity, действующий как CompositeEntity. CoarseGrainedObject будет классом, который содержит зависимые объекты. CompositeEntityPatternDemo , наш демонстрационный класс будет использовать класс Client, чтобы продемонстрировать использование шаблона Composite Entity.

UML-диаграмма составного объекта

Шаг 1

Создать зависимые объекты.

DependentObject1.java

public class DependentObject1 {
	
   private String data;

   public void setData(String data){
      this.data = data; 
   } 

   public String getData(){
      return data;
   }
}

DependentObject2.java

public class DependentObject2 {
	
   private String data;

   public void setData(String data){
      this.data = data; 
   } 

   public String getData(){
      return data;
   }
}

Шаг 2

Создать крупнозернистый объект.

CoarseGrainedObject.java

public class CoarseGrainedObject {
   DependentObject1 do1 = new DependentObject1();
   DependentObject2 do2 = new DependentObject2();

   public void setData(String data1, String data2){
      do1.setData(data1);
      do2.setData(data2);
   }

   public String[] getData(){
      return new String[] {do1.getData(),do2.getData()};
   }
}

Шаг 3

Создать составную сущность.

CompositeEntity.java

public class CompositeEntity {
   private CoarseGrainedObject cgo = new CoarseGrainedObject();

   public void setData(String data1, String data2){
      cgo.setData(data1, data2);
   }

   public String[] getData(){
      return cgo.getData();
   }
}

Шаг 4

Создайте класс Client для использования Composite Entity.

Client.java

public class Client {
   private CompositeEntity compositeEntity = new CompositeEntity();

   public void printData(){
      for (int i = 0; i < compositeEntity.getData().length; i++) {
         System.out.println("Data: " + compositeEntity.getData()[i]);
      }
   }

   public void setData(String data1, String data2){
      compositeEntity.setData(data1, data2);
   }
}

Шаг 5

Используйте клиент для демонстрации использования шаблона проектирования Composite Entity.

CompositeEntityPatternDemo.java

public class CompositeEntityPatternDemo {
   public static void main(String[] args) {
       Client client = new Client();
       client.setData("Test", "Data");
       client.printData();
       client.setData("Second Test", "Data1");
       client.printData();
   }
}

Шаг 6

Проверьте вывод.

 Данные: тест
 Данные: Данные
 Данные: второй тест
 Данные: Данные1

Шаблон доступа к данным

Шаблон доступа к данным или шаблон DAO используется для отделения низкоуровневого API доступа к данным или операций от бизнес-сервисов высокого уровня. Ниже приведены участники в шаблоне доступа к данным.

  • Интерфейс объекта доступа к данным — этот интерфейс определяет стандартные операции, которые должны выполняться над модельным объектом (ами).

  • Объект доступа к данным конкретного класса — этот класс реализует интерфейс выше. Этот класс отвечает за получение данных из источника данных, которым может быть база данных / xml или любой другой механизм хранения.

  • Объект модели или объект значения — это простой объект POJO, содержащий методы get / set для хранения данных, полученных с использованием класса DAO.

Интерфейс объекта доступа к данным — этот интерфейс определяет стандартные операции, которые должны выполняться над модельным объектом (ами).

Объект доступа к данным конкретного класса — этот класс реализует интерфейс выше. Этот класс отвечает за получение данных из источника данных, которым может быть база данных / xml или любой другой механизм хранения.

Объект модели или объект значения — это простой объект POJO, содержащий методы get / set для хранения данных, полученных с использованием класса DAO.

Реализация

Мы собираемся создать объект Student, выступающий в качестве объекта Model или Value. StudentDao — это интерфейс доступа к данным. StudentDaoImpl — это конкретный класс, реализующий интерфейс доступа к данным. DaoPatternDemo , наш демонстрационный класс будет использовать StudentDao, чтобы продемонстрировать использование шаблона объекта доступа к данным.

Диаграмма UML для шаблона доступа к данным

Шаг 1

Создать объект значения.

Student.java

public class Student {
   private String name;
   private int rollNo;

   Student(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public int getRollNo() {
      return rollNo;
   }

   public void setRollNo(int rollNo) {
      this.rollNo = rollNo;
   }
}

Шаг 2

Создать интерфейс доступа к данным.

StudentDao.java

import java.util.List;

public interface StudentDao {
   public List<Student> getAllStudents();
   public Student getStudent(int rollNo);
   public void updateStudent(Student student);
   public void deleteStudent(Student student);
}

Шаг 3

Создать конкретный класс, реализующий интерфейс выше.

StudentDaoImpl.java

import java.util.ArrayList;
import java.util.List;

public class StudentDaoImpl implements StudentDao {
	
   //list is working as a database
   List<Student> students;

   public StudentDaoImpl(){
      students = new ArrayList<Student>();
      Student student1 = new Student("Robert",0);
      Student student2 = new Student("John",1);
      students.add(student1);
      students.add(student2);		
   }
   @Override
   public void deleteStudent(Student student) {
      students.remove(student.getRollNo());
      System.out.println("Student: Roll No " + student.getRollNo() 
         +", deleted from database");
   }

   //retrive list of students from the database
   @Override
   public List<Student> getAllStudents() {
      return students;
   }

   @Override
   public Student getStudent(int rollNo) {
      return students.get(rollNo);
   }

   @Override
   public void updateStudent(Student student) {
      students.get(student.getRollNo()).setName(student.getName());
      System.out.println("Student: Roll No " + student.getRollNo() 
         +", updated in the database");
   }
}

Шаг 4

Используйте StudentDao, чтобы продемонстрировать использование шаблона объекта доступа к данным.

CompositeEntityPatternDemo.java

public class DaoPatternDemo {
   public static void main(String[] args) {
      StudentDao studentDao = new StudentDaoImpl();

      //print all students
      for (Student student : studentDao.getAllStudents()) {
         System.out.println("Student: [RollNo : "
            +student.getRollNo()+", Name : "+student.getName()+" ]");
      }


      //update student
      Student student =studentDao.getAllStudents().get(0);
      student.setName("Michael");
      studentDao.updateStudent(student);

      //get the student
      studentDao.getStudent(0);
      System.out.println("Student: [RollNo : "
         +student.getRollNo()+", Name : "+student.getName()+" ]");		
   }
}

Шаг 5

Проверьте вывод.

 Студент: [RollNo: 0, Имя: Роберт]
 Студент: [RollNo: 1, Имя: Джон]
 Студент: Ролл № 0, обновлено в базе данных
 Студент: [RollNo: 0, Имя: Майкл]

Шаблон переднего контроллера

Шаблон проектирования фронт-контроллера используется для обеспечения централизованного механизма обработки запросов, так что все запросы будут обрабатываться одним обработчиком. Этот обработчик может выполнять аутентификацию / авторизацию / регистрацию или отслеживание запроса, а затем передавать запросы соответствующим обработчикам. Ниже приведены сущности этого типа шаблона проектирования.

  • Front Controller — Единый обработчик для всех видов запросов, поступающих в приложение (веб-интерфейс или рабочий стол).

  • Диспетчер — Front Controller может использовать объект диспетчера, который может отправить запрос соответствующему определенному обработчику.

  • Вид — Вид — это объект, для которого сделаны запросы.

Front Controller — Единый обработчик для всех видов запросов, поступающих в приложение (веб-интерфейс или рабочий стол).

Диспетчер — Front Controller может использовать объект диспетчера, который может отправить запрос соответствующему определенному обработчику.

Вид — Вид — это объект, для которого сделаны запросы.

Реализация

Мы собираемся создать FrontController , Dispatcher, который будет действовать как Front Controller и Dispatcher соответственно. HomeView и StudentView представляют различные виды, для которых запросы могут поступать на фронт-контроллер.

FrontControllerPatternDemo , наш демонстрационный класс будет использовать FrontController для демонстрации шаблона проектирования Front Controller.

UML-схема шаблона переднего контроллера

Шаг 1

Создать представления.

HomeView.java

public class HomeView {
   public void show(){
      System.out.println("Displaying Home Page");
   }
}

StudentView.java

public class StudentView {
   public void show(){
      System.out.println("Displaying Student Page");
   }
}

Шаг 2

Создать Диспетчер.

Dispatcher.java

public class Dispatcher {
   private StudentView studentView;
   private HomeView homeView;
   public Dispatcher(){
      studentView = new StudentView();
      homeView = new HomeView();
   }

   public void dispatch(String request){
      if(request.equalsIgnoreCase("STUDENT")){
         studentView.show();
      }else{
         homeView.show();
      }	
   }
}

Шаг 3

Создать FrontController

Context.java

public class FrontController {
	
   private Dispatcher dispatcher;

   public FrontController(){
      dispatcher = new Dispatcher();
   }

   private boolean isAuthenticUser(){
      System.out.println("User is authenticated successfully.");
      return true;
   }

   private void trackRequest(String request){
      System.out.println("Page requested: " + request);
   }

   public void dispatchRequest(String request){
      //log each request
      trackRequest(request);
      //authenticate the user
      if(isAuthenticUser()){
         dispatcher.dispatch(request);
      }	
   }
}

Шаг 4

Используйте FrontController для демонстрации шаблона проектирования Front Controller.

FrontControllerPatternDemo.java

public class FrontControllerPatternDemo {
   public static void main(String[] args) {
      FrontController frontController = new FrontController();
      frontController.dispatchRequest("HOME");
      frontController.dispatchRequest("STUDENT");
   }
}

Шаг 5

Проверьте вывод.

 Запрошенная страница: ГЛАВНАЯ
 Пользователь успешно авторизован.
 Отображение домашней страницы
 Запрашиваемая страница: СТУДЕНТ
 Пользователь успешно авторизован.
 Отображение страницы студента

Перехват шаблона фильтра

Шаблон проектирования перехватывающего фильтра используется, когда мы хотим выполнить некоторую предварительную / постобработку с запросом или ответом приложения. Фильтры определяются и применяются к запросу перед передачей запроса фактическому целевому приложению. Фильтры могут выполнять аутентификацию / авторизацию / регистрацию или отслеживание запроса, а затем передавать запросы соответствующим обработчикам. Ниже приведены сущности этого типа шаблона проектирования.

  • Фильтр — Фильтр, который будет выполнять определенную задачу до или после выполнения запроса обработчиком запроса.

  • Цепочка фильтров — Цепочка фильтров содержит несколько фильтров и помогает выполнять их в заданном порядке на цели.

  • Target — целевой объект является обработчиком запроса

  • Диспетчер фильтров — Диспетчер фильтров управляет фильтрами и цепочкой фильтров.

  • Клиент — Клиент — это объект, который отправляет запрос в целевой объект.

Фильтр — Фильтр, который будет выполнять определенную задачу до или после выполнения запроса обработчиком запроса.

Цепочка фильтров — Цепочка фильтров содержит несколько фильтров и помогает выполнять их в заданном порядке на цели.

Target — целевой объект является обработчиком запроса

Диспетчер фильтров — Диспетчер фильтров управляет фильтрами и цепочкой фильтров.

Клиент — Клиент — это объект, который отправляет запрос в целевой объект.

Реализация

Мы собираемся создать FilterChain , FilterManager , Target , Client как различные объекты, представляющие наши сущности. AuthenticationFilter и DebugFilter представляют конкретные фильтры.

InterceptingFilterDemo , наш демонстрационный класс будет использовать Client для демонстрации шаблона перехвата фильтров.

Схема UML для перехвата шаблона фильтра

Шаг 1

Создать интерфейс фильтра.

Filter.java

public interface Filter {
   public void execute(String request);
}

Шаг 2

Создать бетонные фильтры.

AuthenticationFilter.java

public class AuthenticationFilter implements Filter {
   public void execute(String request){
      System.out.println("Authenticating request: " + request);
   }
}

DebugFilter.java

public class DebugFilter implements Filter {
   public void execute(String request){
      System.out.println("request log: " + request);
   }
}

Шаг 3

Создать цель

Target.java

public class Target {
   public void execute(String request){
      System.out.println("Executing request: " + request);
   }
}

Шаг 4

Создать цепочку фильтров

FilterChain.java

import java.util.ArrayList;
import java.util.List;

public class FilterChain {
   private List<Filter> filters = new ArrayList<Filter>();
   private Target target;

   public void addFilter(Filter filter){
      filters.add(filter);
   }

   public void execute(String request){
      for (Filter filter : filters) {
         filter.execute(request);
      }
      target.execute(request);
   }

   public void setTarget(Target target){
      this.target = target;
   }
}

Шаг 5

Создать диспетчер фильтров

FilterManager.java

public class FilterManager {
   FilterChain filterChain;

   public FilterManager(Target target){
      filterChain = new FilterChain();
      filterChain.setTarget(target);
   }
   public void setFilter(Filter filter){
      filterChain.addFilter(filter);
   }

   public void filterRequest(String request){
      filterChain.execute(request);
   }
}

Шаг 6

Создать клиента

Client.java

public class Client {
   FilterManager filterManager;

   public void setFilterManager(FilterManager filterManager){
      this.filterManager = filterManager;
   }

   public void sendRequest(String request){
      filterManager.filterRequest(request);
   }
}

Шаг 7

Используйте клиент для демонстрации шаблона перехвата дизайна фильтра.

FrontControllerPatternDemo.java

public class InterceptingFilterDemo {
   public static void main(String[] args) {
      FilterManager filterManager = new FilterManager(new Target());
      filterManager.setFilter(new AuthenticationFilter());
      filterManager.setFilter(new DebugFilter());

      Client client = new Client();
      client.setFilterManager(filterManager);
      client.sendRequest("HOME");
   }
}

Шаг 8

Проверьте вывод.

 Запрос аутентификации: ГЛАВНАЯ
 Журнал запросов: ГЛАВНАЯ
 Выполнение запроса: ГЛАВНАЯ

Шаблон сервисного локатора

Шаблон проектирования локатора сервиса используется, когда мы хотим найти различные сервисы, используя поиск JNDI. Учитывая высокую стоимость поиска JNDI для службы, шаблон Service Locator использует технику кэширования. В первый раз, когда требуется сервис, сервисный локатор ищет в JNDI и кэширует объект сервиса. Дальнейший поиск или аналогичный сервис через Service Locator выполняется в его кеше, что значительно повышает производительность приложения. Ниже приведены сущности этого типа шаблона проектирования.

  • Сервис — Фактический Сервис, который обработает запрос. Ссылка на такую ​​услугу должна быть найдена на сервере JNDI.

  • Context / Initial Context -JNDI Context, содержит ссылку на сервис, используемый для поиска.

  • Сервисный локатор — Сервисный локатор — это единственная точка контакта для получения сервисов посредством поиска JNDI, кэширования сервисов.

  • Cache — кэш для хранения ссылок на сервисы для их повторного использования

  • Клиент — Клиент — это объект, который вызывает сервисы через ServiceLocator.

Сервис — Фактический Сервис, который обработает запрос. Ссылка на такую ​​услугу должна быть найдена на сервере JNDI.

Context / Initial Context -JNDI Context, содержит ссылку на сервис, используемый для поиска.

Сервисный локатор — Сервисный локатор — это единственная точка контакта для получения сервисов посредством поиска JNDI, кэширования сервисов.

Cache — кэш для хранения ссылок на сервисы для их повторного использования

Клиент — Клиент — это объект, который вызывает сервисы через ServiceLocator.

Реализация

Мы собираемся создать ServiceLocator , InitialContext , Cache , Service в качестве различных объектов, представляющих наши сущности. Сервис1 и Сервис2 представляют конкретные услуги.

ServiceLocatorPatternDemo , наш демонстрационный класс действует здесь как клиент и будет использовать ServiceLocator для демонстрации шаблона проектирования локатора службы.

Диаграмма UML шаблона локатора службы

Шаг 1

Создать сервисный интерфейс.

Service.java

public interface Service {
   public String getName();
   public void execute();
}

Шаг 2

Создавайте конкретные услуги.

Service1.java

public class Service1 implements Service {
   public void execute(){
      System.out.println("Executing Service1");
   }

   @Override
   public String getName() {
      return "Service1";
   }
}

Service2.java

public class Service2 implements Service {
   public void execute(){
      System.out.println("Executing Service2");
   }

   @Override
   public String getName() {
      return "Service2";
   }
}

Шаг 3

Создать InitialContext для поиска JNDI

InitialContext.java

public class InitialContext {
   public Object lookup(String jndiName){
      if(jndiName.equalsIgnoreCase("SERVICE1")){
         System.out.println("Looking up and creating a new Service1 object");
         return new Service1();
      }else if (jndiName.equalsIgnoreCase("SERVICE2")){
         System.out.println("Looking up and creating a new Service2 object");
         return new Service2();
      }
      return null;		
   }
}

Шаг 4

Создать кеш

Cache.java

import java.util.ArrayList;
import java.util.List;

public class Cache {

   private List<Service> services;

   public Cache(){
      services = new ArrayList<Service>();
   }

   public Service getService(String serviceName){
      for (Service service : services) {
         if(service.getName().equalsIgnoreCase(serviceName)){
            System.out.println("Returning cached  "+serviceName+" object");
            return service;
         }
      }
      return null;
   }

   public void addService(Service newService){
      boolean exists = false;
      for (Service service : services) {
         if(service.getName().equalsIgnoreCase(newService.getName())){
            exists = true;
         }
      }
      if(!exists){
         services.add(newService);
      }
   }
}

Шаг 5

Создать сервисный локатор

ServiceLocator.java

public class ServiceLocator {
   private static Cache cache;

   static {
      cache = new Cache();		
   }

   public static Service getService(String jndiName){

      Service service = cache.getService(jndiName);

      if(service != null){
         return service;
      }

      InitialContext context = new InitialContext();
      Service service1 = (Service)context.lookup(jndiName);
      cache.addService(service1);
      return service1;
   }
}

Шаг 6

Используйте ServiceLocator, чтобы продемонстрировать шаблон проектирования локатора службы.

ServiceLocatorPatternDemo.java

public class ServiceLocatorPatternDemo {
   public static void main(String[] args) {
      Service service = ServiceLocator.getService("Service1");
      service.execute();
      service = ServiceLocator.getService("Service2");
      service.execute();
      service = ServiceLocator.getService("Service1");
      service.execute();
      service = ServiceLocator.getService("Service2");
      service.execute();		
   }
}

Шаг 7

Проверьте вывод.

 Поиск и создание нового объекта Service1
 Выполнение Сервиса1
 Поиск и создание нового объекта Service2
 Выполнение Service2
 Возврат кешированного объекта Service1
 Выполнение Сервиса1
 Возврат кешированного объекта Service2
 Выполнение Service2

Шаблон переноса объекта

Шаблон Transfer Object используется, когда мы хотим передать данные с несколькими атрибутами в одном кадре от клиента к серверу. Передаточный объект также известен как Value Object. Transfer Object — это простой класс POJO, имеющий методы getter / setter и сериализуемый, чтобы его можно было передавать по сети. Это не имеет никакого поведения. Бизнес-класс на стороне сервера обычно выбирает данные из базы данных и заполняет POJO и отправляет их клиенту или передает их по значению. Для клиента объект передачи доступен только для чтения. Клиент может создать свой собственный объект передачи и передать его на сервер для обновления значений в базе данных за один раз. Ниже приведены сущности этого типа шаблона проектирования.

  • Бизнес-объект — бизнес-служба, которая заполняет объект переноса данными.

  • Передача объекта — простой POJO, имеющий методы только для установки / получения атрибутов.

  • Клиент — Клиент либо запрашивает, либо отправляет объект переноса в бизнес-объект.

Бизнес-объект — бизнес-служба, которая заполняет объект переноса данными.

Передача объекта — простой POJO, имеющий методы только для установки / получения атрибутов.

Клиент — Клиент либо запрашивает, либо отправляет объект переноса в бизнес-объект.

Реализация

Мы собираемся создать StudentBO как Business Object, Student как Transfer Object, представляющий наши объекты.

TransferObjectPatternDemo , наш демонстрационный класс действует здесь как клиент и будет использовать StudentBO и Student для демонстрации шаблона проектирования Transfer Object.

Передача объекта UML-диаграммы

Шаг 1

Создать объект переноса.

StudentVO.java

public class StudentVO {
   private String name;
   private int rollNo;

   StudentVO(String name, int rollNo){
      this.name = name;
      this.rollNo = rollNo;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public int getRollNo() {
      return rollNo;
   }

   public void setRollNo(int rollNo) {
      this.rollNo = rollNo;
   }
}

Шаг 2

Создать бизнес-объект.

StudentBO.java

import java.util.ArrayList;
import java.util.List;

public class StudentBO {
	
   //list is working as a database
   List<StudentVO> students;

   public StudentBO(){
      students = new ArrayList<StudentVO>();
      StudentVO student1 = new StudentVO("Robert",0);
      StudentVO student2 = new StudentVO("John",1);
      students.add(student1);
      students.add(student2);		
   }
   public void deleteStudent(StudentVO student) {
      students.remove(student.getRollNo());
      System.out.println("Student: Roll No " 
      + student.getRollNo() +", deleted from database");
   }

   //retrive list of students from the database
   public List<StudentVO> getAllStudents() {
      return students;
   }

   public StudentVO getStudent(int rollNo) {
      return students.get(rollNo);
   }

   public void updateStudent(StudentVO student) {
      students.get(student.getRollNo()).setName(student.getName());
      System.out.println("Student: Roll No " 
      + student.getRollNo() +", updated in the database");
   }
}

Шаг 3

Используйте StudentBO, чтобы продемонстрировать шаблон проектирования Transfer Object.

TransferObjectPatternDemo.java

public class TransferObjectPatternDemo {
   public static void main(String[] args) {
      StudentBO studentBusinessObject = new StudentBO();

      //print all students
      for (StudentVO student : studentBusinessObject.getAllStudents()) {
         System.out.println("Student: [RollNo : "
         +student.getRollNo()+", Name : "+student.getName()+" ]");
      }

      //update student
      StudentVO student =studentBusinessObject.getAllStudents().get(0);
      student.setName("Michael");
      studentBusinessObject.updateStudent(student);

      //get the student
      studentBusinessObject.getStudent(0);
      System.out.println("Student: [RollNo : "
      +student.getRollNo()+", Name : "+student.getName()+" ]");
   }
}

Шаг 4

Проверьте вывод.