Краткое руководство по шаблонам дизайна
Шаблоны проектирования представляют собой передовой опыт, используемый опытными разработчиками объектно-ориентированного программного обеспечения. Шаблоны проектирования - это решения общих проблем, с которыми разработчики программного обеспечения сталкивались во время разработки программного обеспечения. Эти решения были получены путем проб и ошибок многочисленными разработчиками программного обеспечения в течение довольно значительного периода времени.
Что такое «Банда четырех» (GOF)?
В 1994 году четыре автора: Эрих Гамма, Ричард Хелм, Ральф Джонсон и Джон Влиссидес опубликовали книгу под названием Design Patterns - Elements of Reusable Object-Oriented Software который положил начало концепции шаблона дизайна в разработке программного обеспечения.
Эти авторы вместе известны как Gang of Four (GOF). По мнению этих авторов, шаблоны проектирования в первую очередь основаны на следующих принципах объектно-ориентированного проектирования.
Программа для интерфейса, а не реализация
Предпочитайте композицию объекта наследованию
Использование шаблона дизайна
Шаблоны проектирования используются в разработке программного обеспечения двумя основными способами.
Общая платформа для разработчиков
Шаблоны проектирования содержат стандартную терминологию и относятся к конкретному сценарию. Например, одноэлементный шаблон проектирования означает использование одного объекта, поэтому все разработчики, знакомые с одним шаблоном проектирования, будут использовать один объект и могут сообщить друг другу, что программа следует одноэлементному шаблону.
Лучшие практики
Шаблоны проектирования разрабатывались в течение длительного периода времени, и они обеспечивают наилучшие решения определенных проблем, возникающих при разработке программного обеспечения. Изучение этих шаблонов помогает неопытным разработчикам легко и быстро изучать дизайн программного обеспечения.
Типы паттернов дизайна
Согласно справочнику по шаблонам проектирования Design Patterns - Elements of Reusable Object-Oriented Software, существует 23 шаблона проектирования. Эти шаблоны можно разделить на три категории: творческие, структурные и поведенческие. Мы также обсудим другую категорию шаблонов проектирования: шаблоны проектирования J2EE.
SN | Узор и описание |
---|---|
1 | Creational Patterns Эти шаблоны проектирования позволяют создавать объекты, скрывая логику создания, а не создавать экземпляры объектов напрямую с помощью оператора new. Это дает программе больше гибкости в выборе объектов, которые необходимо создать для данного варианта использования. |
2 | Structural Patterns Эти шаблоны проектирования касаются композиции классов и объектов. Концепция наследования используется для создания интерфейсов и определения способов компоновки объектов для получения новых функций. |
3 | Behavioral Patterns Эти шаблоны проектирования специально предназначены для связи между объектами. |
4 | J2EE Patterns Эти шаблоны проектирования специально связаны с уровнем представления. Эти шаблоны определены Sun Java Center. |
Фабричный шаблон - один из наиболее часто используемых шаблонов проектирования в Java. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон предоставляет один из лучших способов создания объекта.
В шаблоне Factory мы создаем объект, не открывая клиенту логику создания, и ссылаемся на вновь созданный объект, используя общий интерфейс.
Реализация
Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . Фабричный класс ShapeFactory определяется как следующий шаг.
FactoryPatternDemo , наш демонстрационный класс будет использовать ShapeFactory для получения объекта Shape . Он будет передавать информацию ( CIRCLE / RECTANGLE / SQUARE ) в ShapeFactory, чтобы получить тип объекта, который ему нужен.
Шаг 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
Создайте Factory для создания объекта конкретного класса на основе заданной информации.
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
Используйте Factory, чтобы получить объект конкретного класса, передав такую информацию, как тип.
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
Проверьте вывод.
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Шаблоны абстрактной фабрики работают вокруг суперфабрики, которая создает другие фабрики. Этот завод еще называют фабрикой заводов. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон предоставляет один из лучших способов создания объекта.
В шаблоне «Абстрактная фабрика» интерфейс отвечает за создание фабрики связанных объектов без явного указания их классов. Каждая сгенерированная фабрика может предоставлять объекты в соответствии с шаблоном фабрики.
Реализация
Мы собираемся создать интерфейс Shape и конкретный класс, реализующий его. В качестве следующего шага мы создаем абстрактный фабричный класс AbstractFactory. Определен фабричный класс ShapeFactory, который расширяет AbstractFactory. Создается класс FactoryProducer создателя / генератора фабрики.
AbstractFactoryPatternDemo, наш демонстрационный класс использует FactoryProducer для получения объекта AbstractFactory. Он будет передавать информацию (CIRCLE / RECTANGLE / SQUARE для Shape) в AbstractFactory, чтобы получить требуемый тип объекта.
Шаг 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
Создайте класс генератора / производителя Factory, чтобы получить фабрики, передав такую информацию, как Shape
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 shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
//get an object of Shape Rectangle
Shape shape1 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape1.draw();
//get an object of Shape Square
Shape shape2 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape2.draw();
//get 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 .
Шаг 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
Получить единственный объект из класса singleton.
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
Проверьте вывод.
Hello World!
Шаблон Builder создает сложный объект, используя простые объекты и используя пошаговый подход. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон предоставляет один из лучших способов создания объекта.
Класс Builder шаг за шагом строит окончательный объект. Этот строитель не зависит от других объектов.
Реализация
Мы рассмотрели бизнес-пример ресторана быстрого питания, где типичной едой может быть бургер и холодный напиток. Бургер может быть вегетарианским или куриным, и он будет упакован в обертку. Холодный напиток может быть колой или пепси и будет расфасован в бутылку.
Мы собираемся создать интерфейс Item, представляющий продукты питания, такие как гамбургеры и холодные напитки, и конкретные классы, реализующие интерфейс Item, и интерфейс Packing, представляющий упаковку продуктов питания, и конкретные классы, реализующие интерфейс Packing, поскольку гамбургер будет упакован в обертку и холод. напиток будет упакован как бутылка.
Затем мы создаем класс Meal, содержащий ArrayList of Item и MealBuilder, для создания различных типов объектов Meal путем объединения Item . BuilderPatternDemo , наш демонстрационный класс будет использовать MealBuilder для создания Meal .
Шаг 1
Создайте элемент интерфейса, представляющий еду и упаковку.
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
Проверьте вывод.
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0
Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5
Шаблон прототипа относится к созданию повторяющегося объекта с учетом производительности. Этот тип шаблона проектирования относится к шаблону создания, поскольку этот шаблон обеспечивает один из лучших способов создания объекта.
Этот шаблон включает в себя реализацию интерфейса прототипа, который сообщает о создании клона текущего объекта. Этот шаблон используется, когда создание объекта напрямую требует больших затрат. Например, объект должен быть создан после дорогостоящей операции с базой данных. Мы можем кэшировать объект, возвращать его клон при следующем запросе и обновлять базу данных по мере необходимости, тем самым уменьшая количество обращений к базе данных.
Реализация
Мы собираемся создать абстрактный класс Shape и конкретные классы, расширяющие класс Shape . Класс ShapeCache определяется как следующий шаг, который сохраняет объекты формы в Hashtable и возвращает их клон по запросу.
PrototypPatternDemo , наш демонстрационный класс будет использовать класс ShapeCache для получения объекта Shape .
Шаг 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
Проверьте вывод.
Shape : Circle
Shape : Square
Shape : Rectangle
Шаблон адаптера работает как мост между двумя несовместимыми интерфейсами. Этот тип шаблона проектирования относится к структурному шаблону, поскольку он сочетает в себе возможности двух независимых интерфейсов.
Этот шаблон включает один класс, который отвечает за объединение функций независимых или несовместимых интерфейсов. Примером из реальной жизни может быть кардридер, который действует как адаптер между картой памяти и ноутбуком. Вы вставляете карту памяти в устройство чтения карт и устройство чтения карт в портативный компьютер, чтобы карту памяти можно было читать через ноутбук.
Мы демонстрируем использование шаблона адаптера в следующем примере, в котором устройство аудиоплеера может воспроизводить только файлы mp3 и хочет использовать усовершенствованный аудиоплеер, способный воспроизводить файлы vlc и mp4.
Реализация
У нас есть интерфейс MediaPlayer и конкретный класс AudioPlayer, реализующий интерфейс MediaPlayer . AudioPlayer по умолчанию может воспроизводить аудиофайлы в формате mp3.
У нас есть еще один интерфейс AdvancedMediaPlayer и конкретные классы, реализующие интерфейс AdvancedMediaPlayer. Эти классы могут воспроизводить файлы формата vlc и mp4.
Мы хотим, чтобы AudioPlayer воспроизводил и другие форматы. Для этого мы создали класс адаптера MediaAdapter, который реализует интерфейс MediaPlayer и использует объекты AdvancedMediaPlayer для воспроизведения требуемого формата.
AudioPlayer использует класс адаптера MediaAdapter, передавая ему желаемый тип звука, не зная фактического класса, который может воспроизводить желаемый формат. AdapterPatternDemo , наш демонстрационный класс будет использовать класс AudioPlayer для воспроизведения различных форматов.
Шаг 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
Проверьте вывод.
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported
Мост используется там, где нам нужно отделить абстракцию от ее реализации, чтобы они могли различаться независимо. Этот тип шаблона проектирования относится к структурному шаблону, поскольку этот шаблон разделяет класс реализации и абстрактный класс, обеспечивая структуру моста между ними.
Этот шаблон включает интерфейс, который действует как мост, который делает функциональность конкретных классов независимыми от классов средств реализации интерфейса. Оба типа классов могут быть изменены структурно, не влияя друг на друга.
Мы демонстрируем использование паттерна «Мост» в следующем примере, в котором круг может быть нарисован разными цветами с использованием одного и того же метода абстрактного класса, но с разными классами реализатора моста.
Реализация
У нас есть интерфейс DrawAPI, который действует как мост, реализующий мост, и конкретные классы RedCircle , GreenCircle, реализующие интерфейс DrawAPI . Shape - это абстрактный класс, который будет использовать объект DrawAPI . BridgePatternDemo , наш демонстрационный класс будет использовать класс Shape для рисования круга разного цвета.
Шаг 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
Проверьте вывод.
Drawing Circle[ color: red, radius: 10, x: 100, 100]
Drawing Circle[ color: green, radius: 10, x: 100, 100]
Шаблон фильтрации или шаблон критериев - это шаблон проектирования, который позволяет разработчикам фильтровать набор объектов, используя различные критерии, объединяя их в цепочку с помощью логических операций. Этот тип шаблона проектирования относится к структурному шаблону, поскольку этот шаблон объединяет несколько критериев для получения единых критериев.
Реализация
Мы собираемся создать объект Person , интерфейс Criteria и конкретные классы, реализующие этот интерфейс, для фильтрации списка объектов Person . CriteriaPatternDemo , наш демонстрационный класс использует объекты Criteria для фильтрации объектов List of Person на основе различных критериев и их комбинаций.
Шаг 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;
}
}
Шаг 4
Используйте разные критерии и их комбинацию, чтобы отфильтровать людей.
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
Проверьте вывод.
Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : John, Gender : Male, Marital Status : Married ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Females:
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]
Single Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Single Or Females:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]
Составной шаблон используется там, где нам нужно одинаково рассматривать группу объектов как единый объект. Составной шаблон составляет объекты в виде древовидной структуры для представления части, а также всей иерархии. Этот тип шаблона проектирования относится к структурному шаблону, поскольку этот шаблон создает древовидную структуру группы объектов.
Этот шаблон создает класс, содержащий группу собственных объектов. Этот класс предоставляет способы изменения своей группы одинаковых объектов.
Мы демонстрируем использование шаблона Composite на следующем примере, в котором показана иерархия сотрудников в организации.
Реализация
У нас есть класс Employee, который действует как класс актора составного шаблона. CompositePatternDemo , наш демонстрационный класс будет использовать класс Employee для добавления иерархии уровня отделов и печати всех сотрудников.
Шаг 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
Проверьте вывод.
Employee :[ Name : John, dept : CEO, salary :30000 ]
Employee :[ Name : Robert, dept : Head Sales, salary :20000 ]
Employee :[ Name : Richard, dept : Sales, salary :10000 ]
Employee :[ Name : Rob, dept : Sales, salary :10000 ]
Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ]
Employee :[ Name : Laura, dept : Marketing, salary :10000 ]
Employee :[ Name : Bob, dept : Marketing, salary :10000 ]
Шаблон декоратора позволяет добавлять новые функции к существующему объекту без изменения его структуры. Этот тип шаблона проектирования входит в состав структурного шаблона, поскольку этот шаблон действует как оболочка для существующего класса.
Этот шаблон создает класс-декоратор, который обертывает исходный класс и обеспечивает дополнительную функциональность, сохраняя неизменной сигнатуру методов класса.
Мы демонстрируем использование шаблона Decorator в следующем примере, в котором мы украсим фигуру некоторым цветом без изменения класса фигуры.
Реализация
Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . Затем мы создаем абстрактный класс декоратора ShapeDecorator, реализующий интерфейс Shape и имеющий объект Shape в качестве переменной экземпляра.
RedShapeDecorator - это конкретный класс, реализующий ShapeDecorator .
DecoratorPatternDemo , наш демонстрационный класс будет использовать RedShapeDecorator для украшения объектов Shape .
Шаг 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
Проверьте вывод.
Circle with normal border
Shape: Circle
Circle of red border
Shape: Circle
Border Color: Red
Rectangle of red border
Shape: Rectangle
Border Color: Red
Шаблон фасада скрывает сложность системы и предоставляет клиенту интерфейс, с помощью которого он может получить доступ к системе. Этот тип шаблона проектирования относится к структурному шаблону, поскольку этот шаблон добавляет интерфейс к существующей системе, чтобы скрыть ее сложности.
Этот шаблон включает один класс, который предоставляет упрощенные методы, которые требуются клиенту, и делегирует вызовы методам существующих системных классов.
Реализация
Мы собираемся создать интерфейс Shape и конкретные классы, реализующие интерфейс Shape . На следующем шаге определяется класс фасада ShapeMaker .
Класс ShapeMaker использует конкретные классы для делегирования пользовательских вызовов этим классам. FacadePatternDemo , наш демонстрационный класс будет использовать класс ShapeMaker для отображения результатов.
Шаг 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
Проверьте вывод.
Circle::draw()
Rectangle::draw()
Square::draw()
Шаблон Flyweight в основном используется для уменьшения количества создаваемых объектов, уменьшения объема памяти и повышения производительности. Этот тип шаблона проектирования относится к структурному шаблону, поскольку этот шаблон предоставляет способы уменьшить количество объектов, тем самым улучшая структуру объектов, необходимых для приложения.
Шаблон-легковес пытается повторно использовать уже существующие объекты аналогичного типа, сохраняя их, и создает новый объект, когда соответствующий объект не найден. Мы продемонстрируем этот паттерн, нарисовав 20 кругов в разных местах, но создадим только 5 объектов. Доступно только 5 цветов, поэтому свойство цвета используется для проверки уже существующих объектов Circle .
Реализация
Мы собираемся создать интерфейс Shape и конкретный класс Circle, реализующий интерфейс Shape . Фабричный класс ShapeFactory определяется как следующий шаг.
ShapeFactory имеет HashMap of Circle с ключом в качестве цвета объекта Circle . Всякий раз, когда приходит запрос на создание круга определенного цвета в ShapeFactory . ShapeFactory проверяет объект круга в своей HashMap , если объект Circle найден, этот объект возвращается, в противном случае создается новый объект, сохраняется в hashmap для будущего использования и возвращается клиенту.
FlyWeightPatternDemo , наш демонстрационный класс будет использовать ShapeFactory для получения объекта Shape . Он будет передавать информацию ( красный / зеленый / синий / черный / белый ) в ShapeFactory, чтобы получить круг желаемого цвета, который ему нужен.
Шаг 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
Создайте Factory для создания объекта конкретного класса на основе заданной информации.
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
Используйте Factory, чтобы получить объект конкретного класса, передав такую информацию, как цвет.
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
Проверьте вывод.
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 13, y :4, radius :100
Circle: Draw() [Color : Green, x : 21, y :21, radius :100
Circle: Draw() [Color : Blue, x : 55, y :86, radius :100
Circle: Draw() [Color : White, x : 90, y :70, radius :100
Circle: Draw() [Color : Green, x : 78, y :3, radius :100
Circle: Draw() [Color : Green, x : 64, y :89, radius :100
Circle: Draw() [Color : Blue, x : 3, y :91, radius :100
Circle: Draw() [Color : Blue, x : 62, y :82, radius :100
Circle: Draw() [Color : Green, x : 97, y :61, radius :100
Circle: Draw() [Color : Green, x : 86, y :12, radius :100
Circle: Draw() [Color : Green, x : 38, y :93, radius :100
Circle: Draw() [Color : Red, x : 76, y :82, radius :100
Circle: Draw() [Color : Blue, x : 95, y :82, radius :100
В шаблоне Proxy один класс представляет функциональность другого класса. Этот тип шаблона проектирования относится к структурному шаблону.
В шаблоне Proxy мы создаем объект, имеющий исходный объект, чтобы связать его функциональность с внешним миром.
Реализация
Мы собираемся создать интерфейс изображения и конкретные классы, реализующие интерфейс изображения . ProxyImage - это прокси-класс, уменьшающий объем памяти, занимаемый загрузкой объекта RealImage .
ProxyPatternDemo , наш демонстрационный класс будет использовать ProxyImage, чтобы получить объект Image для загрузки и отображения по мере необходимости.
Шаг 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
Проверьте вывод.
Loading test_10mb.jpg
Displaying test_10mb.jpg
Displaying test_10mb.jpg
Как следует из названия, шаблон цепочки ответственности создает цепочку объектов-получателей для запроса. Этот шаблон разделяет отправителя и получателя запроса в зависимости от типа запроса. Этот шаблон относится к шаблонам поведения.
В этом шаблоне обычно каждый приемник содержит ссылку на другой приемник. Если один объект не может обработать запрос, он передает его следующему получателю и так далее.
Реализация
Мы создали абстрактный класс AbstractLogger с уровнем ведения журнала. Затем мы создали три типа регистраторов, расширяющих AbstractLogger . Каждый регистратор проверяет уровень сообщения до своего уровня и, соответственно, print, в противном случае не печатает и не передает сообщение следующему регистратору.
Шаг 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
Проверьте вывод.
Standard Console::Logger: This is an information.
File::Logger: This is an debug level information.
Standard Console::Logger: This is an debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.
Командный шаблон - это шаблон проектирования, управляемый данными, который относится к категории поведенческих шаблонов. Запрос помещается в объект как команда и передается объекту-инициатору. Объект Invoker ищет соответствующий объект, который может обработать эту команду, и передать команду соответствующему объекту, и этот объект выполняет команду.
Реализация
Мы создали интерфейс Order, который действует как команда. Мы создали класс Stock, который действует как запрос. У нас есть конкретные классы команд BuyStock и SellStock, реализующие интерфейс Order, который будет выполнять фактическую обработку команд. Создается брокер классов, который действует как вызывающий объект. Он может принимать заказы и размещать заказы.
Объект- брокер использует шаблон команды, чтобы определить, какой объект будет выполнять какую команду в зависимости от типа команды. CommandPatternDemo , наш демонстрационный класс будет использовать класс Broker для демонстрации шаблона команды.
Шаг 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
Создайте класс вызывающего команды.
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
Проверьте вывод.
Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold
Шаблон интерпретатора позволяет оценивать грамматику или выражение языка. Этот тип шаблона относится к шаблонам поведения. Этот шаблон включает реализацию интерфейса выражения, который сообщает, что нужно интерпретировать конкретный контекст. Этот шаблон используется в синтаксическом анализе SQL, механизме обработки символов и т. Д.
Реализация
Мы собираемся создать интерфейс Expression и конкретные классы, реализующие интерфейс Expression . Определен класс TerminalExpression, который действует как главный интерпретатор рассматриваемого контекста. Другие классы OrExpression , AndExpression используются для создания комбинационных выражений.
InterpreterPatternDemo , наш демонстрационный класс будет использовать класс Expression для создания правил и демонстрации синтаксического анализа выражений.
Шаг 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
Проверьте вывод.
John is male? true
Julie is a married women? true
Шаблон итератора - это очень часто используемый шаблон проектирования в среде программирования Java и .Net. Этот шаблон используется для последовательного доступа к элементам объекта коллекции без необходимости знать его базовое представление.
Паттерн-итератор относится к категории поведенческих паттернов.
Реализация
Мы собираемся создать интерфейс Iterator, описывающий метод навигации, и интерфейс контейнера, который повторно запускает итератор. Конкретные классы, реализующие интерфейс контейнера, будут отвечать за реализацию интерфейса Iterator и его использование.
IteratorPatternDemo , наш демонстрационный класс будет использовать NamesRepository , конкретную реализацию класса для печати имен, хранящихся в виде коллекции в NamesRepository .
Шаг 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
Проверьте вывод.
Name : Robert
Name : John
Name : Julie
Name : Lora
Шаблон посредника используется для уменьшения сложности связи между несколькими объектами или классами. Этот шаблон предоставляет класс-посредник, который обычно обрабатывает все коммуникации между различными классами и поддерживает простую поддержку кода за счет слабой связи. Паттерн посредник подпадает под категорию поведенческих паттернов.
Реализация
Мы демонстрируем шаблон посредника на примере комнаты чата, где несколько пользователей могут отправлять сообщения в комнату чата, и это обязанность комнаты чата - показать сообщения всем пользователям. Мы создали два класса ChatRoom и User . Пользовательские объекты будут использовать метод ChatRoom для обмена сообщениями.
MediatorPatternDemo , наш демонстрационный класс будет использовать объекты User для демонстрации связи между ними.
Шаг 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
Проверьте вывод.
Thu Jan 31 16:05:46 IST 2013 [Robert] : Hi! John!
Thu Jan 31 16:05:46 IST 2013 [John] : Hello! Robert!
Шаблон Memento используется для уменьшения того, где мы хотим восстановить состояние объекта до предыдущего состояния. Образец воспоминания относится к категории поведенческих образцов.
Реализация
Шаблон Memento использует три класса актеров. Memento содержит состояние восстанавливаемого объекта. Создатель создает и сохраняет состояния в объектах Memento и в объекте Caretaker, который отвечает за восстановление состояния объекта из Memento. Мы создали классы Memento , Originator и CareTaker .
MementoPatternDemo , наш демонстрационный класс будет использовать объекты CareTaker и Originator для демонстрации восстановления состояний объекта.
Шаг 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
Проверьте вывод.
Current State: State #4
First saved State: State #2
Second saved State: State #3
Шаблон наблюдателя используется, когда между объектами существует отношение «один ко многим», например, если один объект изменяется, его зависимые объекты должны быть уведомлены автоматически. Паттерн наблюдателя попадает в категорию паттернов поведения.
Реализация
Шаблон наблюдателя использует три класса акторов. Субъект, наблюдатель и клиент. Subject, объект, имеющий методы для присоединения и открепления наблюдателей от клиентского объекта. Мы создали классы Subject , абстрактный класс Observer и конкретные классы, расширяющие абстрактный класс Observer .
ObserverPatternDemo , наш демонстрационный класс будет использовать Subject и конкретные объекты класса, чтобы показать шаблон наблюдателя в действии.
Шаг 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
Проверьте вывод.
First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010
В шаблоне состояния поведение класса изменяется в зависимости от его состояния. Этот тип шаблона проектирования относится к шаблону поведения.
В шаблоне состояния мы создаем объекты, которые представляют различные состояния, и объект контекста, поведение которого меняется при изменении его объекта состояния.
Реализация
Мы собираемся создать государство интерфейса , определяющие действия и конкретные классы государственных , реализующие государственный интерфейс. Контекст - это класс, несущий состояние.
StaePatternDemo , наш демонстрационный класс будет использовать объекты Context и состояния, чтобы продемонстрировать изменение поведения Context в зависимости от типа состояния, в котором он находится.
Шаг 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
Проверьте вывод.
Player is in start state
Start State
Player is in stop state
Stop State
В шаблоне «нулевой объект» нулевой объект заменяет проверку экземпляра нулевого объекта. Вместо того, чтобы ставить проверку if на нулевое значение, Null Object отражает отношение ничего не делать. Такой объект Null также может использоваться для обеспечения поведения по умолчанию в случае, если данные недоступны.
В шаблоне нулевого объекта мы создаем абстрактный класс, определяющий различные операции, которые должны быть выполнены, конкретизируем классы, расширяющие этот класс, и класс нулевого объекта, который ничего не делает для реализации этого класса, и будет использоваться без всякого видения там, где нам нужно проверить нулевое значение.
Реализация
Мы собираемся создать абстрактный класс AbstractCustomer, определяющий операции, здесь имя клиента и конкретные классы, расширяющие класс AbstractCustomer . Заводской класс CustomerFactory создается для возврата объектов RealCustomer или NullCustomer в зависимости от переданного ему имени клиента.
NullPatternDemo , наш демонстрационный класс будет использовать CustomerFactory для демонстрации использования шаблона Null Object.
Шаг 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
Проверьте вывод.
Customers
Rob
Not Available in Customer Database
Julie
Not Available in Customer Database
В шаблоне стратегии поведение класса или его алгоритм можно изменить во время выполнения. Этот тип шаблона проектирования относится к шаблону поведения.
В шаблоне стратегии мы создаем объекты, которые представляют различные стратегии и объект контекста, поведение которого зависит от его объекта стратегии. Объект стратегии изменяет алгоритм выполнения объекта контекста.
Реализация
Мы собираемся создать интерфейс стратегии, определяющий классы действий и конкретных стратегий, реализующих интерфейс стратегии . Контекст - это класс, который использует стратегию.
StrategyPatternDemo , наш демонстрационный класс будет использовать объекты контекста и стратегии, чтобы продемонстрировать изменение поведения контекста на основе стратегии, которую он развертывает или использует.
Шаг 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, чтобы его нельзя было переопределить. Cricket и Football - это конкретные классы, расширяющие Game и переопределяющие ее методы.
TemplatePatternDemo , наш демонстрационный класс будет использовать Game для демонстрации использования шаблона шаблона.
Шаг 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
Используйте Игровой метод шаблона игры «s () , чтобы продемонстрировать определенный способ играть игру.
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
Проверьте вывод.
Cricket Game Initialized! Start playing.
Cricket Game Started. Enjoy the game!
Cricket Game Finished!
Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!
В шаблоне посетителя мы используем класс посетителя, который изменяет алгоритм выполнения класса элемента. Таким образом, алгоритм выполнения элемента может меняться в зависимости от посетителя. Этот шаблон относится к категории шаблонов поведения. Согласно шаблону объект элемента должен принять объект посетителя, чтобы объект посетителя обрабатывал операцию с объектом элемента.
Реализация
Мы собираемся создать интерфейс ComputerPart, определяющий операцию принятия. Keyboard , Mouse , Monitor и Computer - это конкретные классы, реализующие интерфейс ComputerPart . Мы определим другой интерфейс ComputerPartVisitor, который будет определять операции класса посетителя. Компьютер использует конкретного посетителя для выполнения соответствующего действия.
VisitorPatternDemo , наш демонстрационный класс будет использовать классы Computer , ComputerPartVisitor для демонстрации использования шаблона посетителя.
Шаг 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
Проверьте вывод.
Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.
Шаблон MVC означает шаблон модель-представление-контроллер. Этот шаблон используется для разделения проблем приложения.
Model- Модель представляет собой объект или JAVA POJO, несущий данные. Он также может иметь логику для обновления контроллера, если его данные изменяются.
View - Представление представляет собой визуализацию данных, содержащихся в модели.
Controller- Контроллер действует как на модель, так и на вид. Он управляет потоком данных в объект модели и обновляет представление при изменении данных. Он разделяет представление и модель.
Реализация
Мы собираемся создать объект Student, выступающий в качестве модели. StudentView будет классом представления, который может печатать сведения о студенте на консоли, а StudentController - это класс контроллера, отвечающий за хранение данных в объекте Student и соответствующее обновление представления StudentView .
MVCPatternDemo , наш демонстрационный класс будет использовать StudentController для демонстрации использования шаблона MVC.
Шаг 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
Проверьте вывод.
Student:
Name: Robert
Roll No: 10
Student:
Name: Julie
Roll No: 10
Шаблон бизнес-делегата используется для разделения уровня презентации и бизнес-уровня. Он в основном используется для сокращения функциональности взаимодействия или удаленного поиска в коде бизнес-уровня в коде уровня представления. На бизнес-уровне мы следуем за сущностями.
Client - Код уровня представления может быть JSP, сервлетом или Java-кодом пользовательского интерфейса.
Business Delegate - Единый класс точки входа для клиентских объектов, обеспечивающий доступ к методам бизнес-сервиса.
LookUp Service - Объект службы поиска отвечает за получение относительной бизнес-реализации и предоставляет доступ бизнес-объекта к объекту бизнес-делегата.
Business Service- Интерфейс бизнес-сервиса. Конкретные классы реализуют этот бизнес-сервис, чтобы предоставить фактическую логику реализации бизнес-процесса.
Реализация
Мы собираемся создать Client , BusinessDelegate , BusinessService , LookUpService , JMSService и EJBService, представляющие различные сущности шаблона Business Delegate.
BusinessDelegatePatternDemo , наш демонстрационный класс будет использовать BusinessDelegate и Client для демонстрации использования шаблона Business Delegate.
Шаг 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
Проверьте вывод.
Processing task by invoking EJB Service
Processing task by invoking JMS Service
Шаблон Composite Entity используется в механизме сохранения EJB. Составной объект - это объектный компонент EJB, который представляет граф объектов. Когда составной объект обновляется, внутренне зависимые объекты bean обновляются автоматически как управляемые объектным bean EJB. Ниже приведены участники Composite Entity Bean.
Composite Entity - Это первичный объектный компонент. Он может быть крупнозернистым или может содержать крупнозернистый объект, который будет использоваться для целей сохранения.
Coarse-Grained Object-Этот объект содержит зависимые объекты. Он имеет собственный жизненный цикл, а также управляет жизненным циклом зависимых объектов.
Dependent Object - Зависимые объекты - это объект, жизненный цикл которого зависит от объекта Coarse-Grained.
Strategies - Стратегии представляют, как реализовать составную сущность.
Реализация
Мы собираемся создать объект CompositeEntity, действующий как CompositeEntity. CoarseGrainedObject будет классом, который содержит зависимые объекты. CompositeEntityPatternDemo , наш демонстрационный класс будет использовать класс Client для демонстрации использования шаблона Composite Entity.
Шаг 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
Проверьте вывод.
Data: Test
Data: Data
Data: Second Test
Data: Data1
Шаблон объекта доступа к данным или шаблон DAO используется для отделения низкоуровневого доступа к данным API или операций от бизнес-сервисов высокого уровня. Ниже приведены участники шаблона объекта доступа к данным.
Data Access Object Interface - Этот интерфейс определяет стандартные операции, выполняемые с объектом (объектами) модели.
Data Access Object concrete class-Этот класс реализует вышеуказанный интерфейс. Этот класс отвечает за получение данных из источника данных, которым может быть база данных / xml или любой другой механизм хранения.
Model Object or Value Object - Этот объект представляет собой простой POJO, содержащий методы get / set для хранения данных, полученных с использованием класса DAO.
Реализация
Мы собираемся создать объект Student, действующий как объект модели или значения. StudentDao - это объектный интерфейс доступа к данным. StudentDaoImpl - это конкретный класс, реализующий интерфейс объекта доступа к данным. DaoPatternDemo , наш демонстрационный класс будет использовать StudentDao для демонстрации использования шаблона объекта доступа к данным.
Шаг 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
Проверьте вывод.
Student: [RollNo : 0, Name : Robert ]
Student: [RollNo : 1, Name : John ]
Student: Roll No 0, updated in the database
Student: [RollNo : 0, Name : Michael ]
Шаблон проектирования фронт-контроллера используется для обеспечения централизованного механизма обработки запросов, так что все запросы будут обрабатываться одним обработчиком. Этот обработчик может выполнять аутентификацию / авторизацию / регистрацию или отслеживание запроса, а затем передавать запросы соответствующим обработчикам. Ниже приведены сущности этого типа шаблона проектирования.
Front Controller - Единый обработчик для всех типов запросов, поступающих в приложение (веб-интерфейс или настольный компьютер).
Dispatcher - Front Controller может использовать объект диспетчера, который может отправлять запрос соответствующему конкретному обработчику.
View - Просмотры - это объект, для которого сделаны запросы.
Реализация
Мы собираемся создать FrontController , Dispatcher, который будет действовать как Front Controller и Dispatcher соответственно. HomeView и StudentView представляют различные представления, запросы на которые могут поступать на фронт-контроллер.
FrontControllerPatternDemo , наш демонстрационный класс будет использовать FrontController для демонстрации шаблона проектирования фронтального контроллера.
Шаг 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, чтобы продемонстрировать шаблон проектирования фронтального контроллера.
FrontControllerPatternDemo.java
public class FrontControllerPatternDemo {
public static void main(String[] args) {
FrontController frontController = new FrontController();
frontController.dispatchRequest("HOME");
frontController.dispatchRequest("STUDENT");
}
}
Шаг 5
Проверьте вывод.
Page requested: HOME
User is authenticated successfully.
Displaying Home Page
Page requested: STUDENT
User is authenticated successfully.
Displaying Student Page
Шаблон проектирования перехватывающего фильтра используется, когда мы хотим выполнить некоторую предварительную / постобработку с запросом или ответом приложения. Фильтры определяются и применяются к запросу перед передачей запроса в фактическое целевое приложение. Фильтры могут выполнять аутентификацию / авторизацию / регистрацию или отслеживание запроса, а затем передавать запросы соответствующим обработчикам. Ниже приведены сущности этого типа шаблона проектирования.
Filter - Фильтр, который будет выполнять определенную задачу до или после выполнения запроса обработчиком запроса.
Filter Chain - Цепочка фильтров содержит несколько фильтров и помогает выполнять их в определенном порядке на цели.
Target - Целевой объект - обработчик запроса
Filter Manager - Менеджер фильтров управляет фильтрами и цепочкой фильтров.
Client - Клиент - это объект, который отправляет запрос целевому объекту.
Реализация
Мы собираемся создать FilterChain , FilterManager , Target , Client как различные объекты, представляющие наши сущности. AuthenticationFilter и DebugFilter представляют собой конкретные фильтры.
InterceptingFilterDemo , наш демонстрационный класс будет использовать Client для демонстрации шаблона проектирования перехватывающего фильтра.
Шаг 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
Проверьте вывод.
Authenticating request: HOME
request log: HOME
Executing request: HOME
Шаблон проектирования локатора сервисов используется, когда мы хотим найти различные сервисы с помощью поиска JNDI. Учитывая высокую стоимость поиска JNDI для службы, шаблон Service Locator использует технику кэширования. В первый раз, когда служба требуется, Service Locator ищет в JNDI и кэширует объект службы. Дальнейший поиск или та же услуга через Service Locator выполняется в его кеше, что в значительной степени улучшает производительность приложения. Ниже приведены сущности этого типа шаблона проектирования.
Service- Актуальная служба, которая обработает запрос. Ссылку на такую услугу следует искать на сервере JNDI.
Context / Initial Context -JNDI Context, содержит ссылку на службу, используемую для поиска.
Service Locator - Service Locator - это единая точка контакта для получения услуг с помощью поиска JNDI, кэширования услуг.
Cache - Кэш для хранения ссылок на сервисы для их повторного использования
Client - Клиент - это объект, который вызывает сервисы через ServiceLocator.
Реализация
Мы собираемся создать ServiceLocator , InitialContext , Cache , Service как различные объекты, представляющие наши сущности. Service1 и Service2 представляют конкретные услуги.
ServiceLocatorPatternDemo , наш демонстрационный класс выступает здесь в качестве клиента и будет использовать ServiceLocator для демонстрации шаблона проектирования Service Locator.
Шаг 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, чтобы продемонстрировать шаблон проектирования Service Locator.
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
Проверьте вывод.
Looking up and creating a new Service1 object
Executing Service1
Looking up and creating a new Service2 object
Executing Service2
Returning cached Service1 object
Executing Service1
Returning cached Service2 object
Executing Service2
Шаблон Transfer Object используется, когда мы хотим передать данные с несколькими атрибутами за один прием от клиента к серверу. Объект передачи также известен как объект-значение. Transfer Object - это простой класс POJO, имеющий методы получения / установки и сериализуемый, чтобы его можно было передавать по сети. У него нет никакого поведения. Бизнес-класс на стороне сервера обычно извлекает данные из базы данных, заполняет POJO и отправляет его клиенту или передает его по значению. Для клиента объект передачи доступен только для чтения. Клиент может создать свой собственный объект передачи и передать его серверу для обновления значений в базе данных за один раз. Ниже приведены сущности этого типа шаблона проектирования.
Business Object - Бизнес-сервис, который заполняет объект передачи данными.
Transfer Object -Простой POJO, имеющий методы только для установки / получения атрибутов.
Client - Клиент либо запрашивает, либо отправляет объект передачи бизнес-объекту.
Реализация
Мы собираемся создать StudentBO как бизнес-объект, Student как объект передачи, представляющий наши сущности.
TransferObjectPatternDemo , наш демонстрационный класс действует здесь как клиент и будет использовать StudentBO и Student для демонстрации шаблона проектирования объекта передачи.
Шаг 1
Создать объект передачи.
СтудентVO.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
Создать бизнес-объект.
СтудентBO.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, чтобы продемонстрировать шаблон проектирования переносимого объекта.
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
Проверьте вывод.
Student: [RollNo : 0, Name : Robert ]
Student: [RollNo : 1, Name : John ]
Student: Roll No 0, updated in the database
Student: [RollNo : 0, Name : Michael ]