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

Нет, Getter и Setters в Tymdercript & JavaScript не бесполезны

В этом блоге мы говорим о полезности Getter и Setters в современном веб-разработке. Они бесполезны? Когда он имеет смысл использовать их? Геттерс и загадки (также известные как доступники) были введены в JavaScript, когда ECMAScript 5 (2009) был выпущен. Дело в том, что есть

Автор оригинала: Khalil Stemmler.

Геттерс и загадки (также известные как доступ к доступам) были введены в JavaScript, когда ECMAScript 5 (2009) был выпущен.

Дело в том, что есть много путаницы по поводу их полезности и почему вы даже хотите их использовать.

Я наткнулся на это Reddit Thread где обсуждение было о том, если бы они были анти-образцом.

К сожалению, общий консенсус нити был «да». Я думаю, что это потому, что большинство ваших интерфейсных программиров на ежедневной основе не требует полезности, которые предлагают Getter и Getters.

Хотя я не согласен с Getter и Setters, будучи антиблокировкой В целом Отказ У них много полезности в нескольких разных случаях.

Для чего они?

Getter и Getters – это еще один способ обеспечить доступ к свойствам объекта.

Тривиальное использование может выглядеть так:

interface ITrackProps {
  name: string;
  artist: string;
}

class Track {  
  private props: ITrackProps;

  get name (): string {
    return this.props.name;
  }

  set name (name: string) {
	  this.props.name = name;
  }

  get artist (): string {
    return this.props.artist;
  }

  set artist (artist: string) {
	  this.props.artist = artist;
  }

  constructor (props: ITrackProps) {
    this.props = props;
  } 

  public play (): void {	
	  console.log(`Playing ${this.name} by ${this.artist}`);
  }
}

Вопрос становится: «Почему бы не просто использовать атрибуты обычного класса?»

Ну, в этом случае Мы могли бы Отказ

interface ITrackProps {
  name: string;
  artist: string;
}

class Track {  
  public name: string;
  public artist: string;

  constructor (name: string, artist: string;) {
    this.name = name;
    this.artist = artist;
  } 

  public play (): void {	
	  console.log(`Playing ${this.name} by ${this.artist}`);
  }
}

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

Предотвращение моделей анемичных домен

Ты помнишь, что Модель анемии домена является? Один из самых ранних способов понюхать модель анемической доправки, если есть Getter и Benters для каждый атрибут Из ваших объектов доменов (то есть: Set Операции, которые не имеют смысла к удельным языку домен, подвергаются воздействию).

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

Рассмотрим этот пример:

class User {
  // Bad. You can now `set` the user id.
  // When would you ever need to mutate a user's id to a
  // different identifier? Is that safe? Should you be able to?
  public id: UserId;

  constuctor (id: UserId) {
    this.id = id;
  }
}

В домене, управляемом доменным дизайном, чтобы предотвратить анемичную доменную модель и продвинуться вперед создание удельного языка домена, это Действительно важно для нас до Только разоблачить операции, которые действительны для домена Отказ

Это означает Понимание домена, которую вы работаете в Отказ

Я поставим себя для проверки. Давайте посмотрим на Винил класс от Белая этикетка , приложение Vinyl-Trading с открытым исходным кодом, построенным с помощью Tymdercript с использованием доменной конструкции.

import { AggregateRoot } from "../../core/domain/AggregateRoot";
import { UniqueEntityID } from "../../core/domain/UniqueEntityID";
import { Result } from "../../core/Result";
import { Artist } from "./artist";
import { Genre } from "./genre";
import { TraderId } from "../../trading/domain/traderId";
import { Guard } from "../../core/Guard";
import { VinylCreatedEvent } from "./events/vinylCreatedEvent";
import { VinylId } from "./vinylId";

interface VinylProps {
  traderId: TraderId;
  title: string;
  artist: Artist;
  genres: Genre[];
  dateAdded?: Date;
}

export type VinylCollection = Vinyl[];

export class Vinyl extends AggregateRoot {

  public static MAX_NUMBER_GENRES_PER_VINYL = 3;

  // ? 1. Facade. The VinylId key doesn't actually exist
  // as a property of VinylProps, yet- we still need
  // to provide access to it.

  get vinylId(): VinylId {
    return VinylId.create(this.id)
  }

  get title (): string {
    return this.props.title;
  }

  // ? 2. All of these properties are nested one layer
  // deep as props so that we can control access 
  // and mutations to the ACTUAL values.

  get artist (): Artist {
    return this.props.artist
  }

  get genres (): Genre[] {
    return this.props.genres;
  }

  get dateAdded (): Date {
    return this.props.dateAdded;
  }

  // ? 3. You'll notice that there are no setters so far because 
  // it doesn't make sense for us to be able to change any of these
  // things after it has been created

  get traderId (): TraderId {
    return this.props.traderId;
  }

  // ? 4. This approach is called "Encapsulate Collection". We
  // will need to add genres, yes. But we still don't expose the
  // setter because there's some invariant logic here that we want to
  // ensure is enforced.
  // Invariants: 
  // https://khalilstemmler.com/wiki/invariant/

  public addGenre (genre: Genre): void {
    const maxLengthExceeded = this.props.genres
      .length >= Vinyl.MAX_NUMBER_GENRES_PER_VINYL;

    const alreadyAdded = this.props.genres
      .find((g) => g.id.equals(genre.id));

    if (!alreadyAdded && !maxLengthExceeded) {
      this.props.genres.push(genre);
    }
  }

  // ? 5. Provide a way to remove as well.

  public removeGenre (genre: Genre): void {
    this.props.genres = this.props.genres
      .filter((g) => !g.id.equals(genre.id));
  }

  private constructor (props: VinylProps, id?: UniqueEntityID) {
    super(props, id);
  }

  // ? 6. This is how we create Vinyl. After it's created, all properties 
  // effectively become "read only", except for Genre because that's all that
  // makes sense to enabled to be mutated.

  public static create (props: VinylProps, id?: UniqueEntityID): Result {
    const propsResult = Guard.againstNullOrUndefinedBulk([
      { argument: props.title, argumentName: 'title' },
      { argument: props.artist, argumentName: 'artist' },
      { argument: props.genres, argumentName: 'genres' },
      { argument: props.traderId, argumentName: 'traderId' }
    ]);

    if (!propsResult.succeeded) {
      return Result.fail(propsResult.message)
    } 

    const vinyl = new Vinyl({
      ...props,
      dateAdded: props.dateAdded ? props.dateAdded : new Date(),
      genres: Array.isArray(props.genres) ? props.genres : [],
    }, id);
    const isNewlyCreated = !!id === false;

    if (isNewlyCreated) {
      // ? 7. This is why we need VinylId. To provide the identifier
      // for any subscribers to this domain event.
      vinyl.addDomainEvent(new VinylCreatedEvent(vinyl.vinylId))
    }

    return Result.ok(vinyl);
  }
}

Выступая в качестве фасада, поддержание готовности ценностей, применение моделей выразительности, инкапсулирующих коллекций и Создание доменных событий Некоторые очень твердые случаи использования для Getter и Setters в Дизайн, управляемый доменом Отказ

Изменить обнаружение в Vue.js

Vue.js Один из более новых передних фрагментов, гордится быть очень быстрыми и реактивными.

Причина, почему Vue.js так эффективно изменяет обнаружение, потому что они используют Object.DefineProperty () API к Смотреть Для изменений на ваши модели просмотра!

От Vue.js документов по реактивности,

При прохождении простого объекта JavaScript к экземпляру VUE в качестве опции данных Vue будет проходить через все его свойства и преобразовать их в Getter/Benters с использованием объекта. Getter/Setters невидимы для пользователя, но под капотом они позволяют vue для выполнения зависимостей-отслеживания и уведомления об изменении, когда свойства доступны или изменены. – Vue.js Документы: Реактивность

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

Продвинутый блог Teamscript & Node.js

Если вам понравилось эту статью, вы должны Проверьте мой блог Отказ Я пишу о Расширенные типографы и Node.js лучшие практики для крупномасштабных приложений И учить разработчикам, как написать гибкое обслуживание программного обеспечения.