Автор оригинала: 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 лучшие практики для крупномасштабных приложений И учить разработчикам, как написать гибкое обслуживание программного обеспечения.