Рубрики
Без рубрики

Понимание конструкции шаблонов: Нулевый объект

В этой статье я собираюсь описать, что такое шаблон NULL-объекта; И как и когда это следует применять. Этот паттерн не включен в классическую книгу с рисунком, но сначала она была опубликована на графических языках программы, и она широко используется, чтобы избежать сложности. Tagged с JavaScript, Teamscript, Pattern Design, Clean Code.

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

В этой статье я собираюсь описать, что Шаблон Null-Object – ; И как и когда это следует применять. Этот шаблон не включен В классической книге узор, но она была впервые опубликована в Узорные языки программы И он широко используется, чтобы избежать сложности.

Узор NULL объекта: основная идея

В объектно-ориентированном программировании, A Нулевый объект является объектом без ссылки на ссылка или с определенным нейтральным («нулевым») поведением. Шаблон дизайна NULL объекта описывает использование таких объектов и их поведение (или их отсутствие). — Википедия

Основной особенностью этой картины является то, что это позволяет избежать сложности в нашем коде. На большинстве языков, таких как Java, C # или JavaScript, ссылки могут быть нулевыми. В зависимости от нашей бизнес-логики, проверка кода может потребоваться, чтобы они не были нулевыми, прежде чем вызывать какие-либо методы, потому что методы, как правило, не могут быть вызваны на нулевые ссылки.

Подводя итоги, шаблон Null Object позволяет избежать условной сложности с использованием объектов, а не примитивных типов. Диаграмма UML этой картины является следующим:

Класс AbramObject – это абстрактный класс, который определяет различные операции, которые должны быть реализованы в RealObject и объекте «NULL» или «по умолчанию» (Nullobject). RealObject будет выполнять операцию для каждого реального объекта, в то время как Nullobject не сделает ничего, либо вы хотите сделать операцию по умолчанию в этом объекте.

Шаблон NULL-объекта: Когда использовать

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

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

Узор Null Object: Преимущества

Узор NULL-объекта имеет несколько преимуществ, обобщенных в следующих моментах:

  • Определяет классовые иерархии, состоящие из реальных объектов и нулевых объектов.

  • Нулевые объекты могут быть использованы вместо реальных объектов, когда ожидается, что объект ничего не будет делать.

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

Узор NULL объекта – пример 1: Мир Сайяна (проблема)

Теперь я покажу вам, как вы можете реализовать этот шаблон с помощью JavaScript/Teadercript. Перед нанесением шаблона интересно знать о проблеме, которую вы пытаетесь решить. Далее мы дадим контекст на наш пример. Представьте, что у нас есть класс под названием Saiyan, который позволит нам моделировать атрибуты и методы нашей дорогой Саиян Отказ Этот класс реализует интерфейс Isaiyan, который четко определяет характеристики, которые каждый объект должен удовлетворять, чтобы быть настоящим Саиян Отказ Завод под названием Saiyanfactory используется для создания Саиян объекты. Этот класс тезирует нас от того места, откуда приходит Саиян, может быть создан из ОЗУ, запросов в базе данных или сложном алгоритме для изготовления новых объектов.

Наша проблема в качестве разработчиков возникает в классах, которые выступают в качестве клиента и используют нашу фабрику. В следующем клиентском коде мы вызовили метод Getsaiyan для получения нескольких Саиян конкретно мы создали Вегета , Боб , Сон Гоку и Лора Отказ Я понимаю, что читатели знают, что единственный саян из предыдущего списка Вегетация и Сын Гоку ; И поэтому оба Боб и Лора не может быть изготовлено как объекты типа Saiyan.

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

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

Следовательно, мы получаем следующую диаграмму UML.

Исаев и Саиян Код связан следующий:

export interface ISaiyan {
  name: string;
  power: number;
}
/****/

import { ISaiyan } from './saiyan.interface';

export class Saiyan {
  protected name: string;
  protected power: number;

  constructor({ name, power }: ISaiyan) {
    this.name = name;
    this.power = power;
  }
  getName(): string {
    return this.name;
  }

  public toString(): string {
    return `${this.name} - ${this.power}`;
  }
}

Код, связанный с заводом, который является базой данных, Mock, является следующим:

import { Saiyan } from './saiyan.class';

export class SaiyanFactory {
  public saiyans = [
    { name: 'Son Goku', power: 1000 },
    { name: 'Son Gohan', power: 800 },
    { name: 'Vegeta', power: 950 },
  ];

  public getSaiyan(name: string): Saiyan | null {
    // Mock Database find
    for (const saiyan of this.saiyans) {
      if (saiyan.name === name) {
        return new Saiyan(saiyan);
      }
    }
    return null;
  }
}

Наконец, код, связанный с клиентом, где условная сложность экспоненциальна из-за нулевых объектов с завода.

import { SaiyanFactory } from './saiyan-factory.class';

const saiyanFactory = new SaiyanFactory();
const saiyan1 = saiyanFactory.getSaiyan('Vegeta');
const saiyan2 = saiyanFactory.getSaiyan('Bob');
const saiyan3 = saiyanFactory.getSaiyan('Son Goku');
const saiyan4 = saiyanFactory.getSaiyan('Laura');

console.log('Saiyan');
if (saiyan1 !== null) {
  console.log(saiyan1.toString());
} else {
  console.log('Not Available in Customer Database');
}
if (saiyan2 !== null) {
  console.log(saiyan2.toString());
} else {
  console.log('Not Available in Customer Database');
}
if (saiyan3 !== null) {
  console.log(saiyan3.toString());
} else {
  console.log('Not Available in Customer Database');
}
if (saiyan4 !== null) {
  console.log(saiyan4.toString());
} else {
  console.log('Not Available in Customer Database');
}

Шаблон Null Object – пример 1: Мир Сайяна (решение)

Решение состоит в том, чтобы использовать шаблон NULL-объекта. Новая диаграмма UML, использующая этот шаблон, показана ниже:

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

Поэтому мы устранили сложность от клиентов, и это сделало благодаря небольшому изменению нашей внутренней структуре класса. Завод вместо того, чтобы использовать только класс Saiyan, из которого генерируются новый сайян, создаст простое наследование (жесткий состав) от этого класса Saiyan, порождающий два новых класса Реалсайян и Nullsaiyan , преобразуя класс Saiyan в абстрактный класс.

Класс Saiyan теперь определяет методы, которые должны реализовать все полученные классы Saiyan, логика Saiyan, найденной в базе знаний, будет реализована в Реалсайян Класс, в то время как логика объектов не найден (NULL) или даже если мы хотим реализовать поведение по умолчанию в Nullsaiyan сорт.

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

Теперь мы посмотрим на код, сгенерированный с реализацией этого шаблона:

import { SaiyanFactory } from './saiyan-factory.class';

const saiyanFactory = new SaiyanFactory();
const saiyan1 = saiyanFactory.getSaiyan('Vegeta');
const saiyan2 = saiyanFactory.getSaiyan('Bob');
const saiyan3 = saiyanFactory.getSaiyan('Son Goku');
const saiyan4 = saiyanFactory.getSaiyan('Laura');

console.log('Saiyan');
console.log(saiyan1.toString());
console.log(saiyan2.toString());
console.log(saiyan3.toString());
console.log(saiyan4.toString());

Код, связанный с заводом, который возвращает два вида объектов, является следующим:

import { AbstractSaiyan } from './saiyan.class';
import { NullSaiyan } from './null-saiyan.class';
import { RealSaiyan } from './real-saiyan.class';

export class SaiyanFactory {
  public saiyans = [
    { name: 'Son Goku', power: 1000 },
    { name: 'Son Gohan', power: 800 },
    { name: 'Vegeta', power: 950 },
  ];

  public getSaiyan(name: string): AbstractSaiyan {
    for (const saiyan of this.saiyans) {
      if (saiyan.name === name) {
        return new RealSaiyan(saiyan);
      }
    }
    return new NullSaiyan();
  }
}

Код, связанный с Абстрацияйян следующее:

export abstract class AbstractSaiyan {
  protected name: string;
  protected power: number;
  public abstract getName(): string;
  public abstract toString(): string;
}

Наконец, код, связанный с каждым конкретным классом, является следующим:

import { AbstractSaiyan } from './saiyan.class';
import { Saiyan } from './saiyan.interface';

export class RealSaiyan extends AbstractSaiyan {
  constructor({ name, power }: Saiyan) {
    super();
    this.name = name;
    this.power = power;
  }

  getName(): string {
    return this.name;
  }
  toString(): string {
    return `${this.name} - ${this.power}`;
  }
}
import { AbstractSaiyan } from './saiyan.class';

export class NullSaiyan extends AbstractSaiyan {
  public getName(): string {
    return 'Not Available in Saiyan Database';
  }
  toString(): string {
    return 'Not Available in Saiyan Database';
  }
}

Я создал несколько сценариев NPM, которые запускают примеры кода, показанные здесь после применения шаблона NULL-OJBECT.

NPM Run Пример1 – проблема

NPM Run Example1-Solution-1

Заключение

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

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

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

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

Больше больше больше…

Оригинал: “https://dev.to/carlillo/understanding-design-patterns-null-object-k9d”