2016-08-28 6 views
3

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

Глядя на некоторые приложения Angular2, я всегда вижу, что эта концепция нарушена.

export class TodoService { 
    todos: Array<TodoData> = []; 

    addTodo(todo: string) { 
    this.todos.push({ 
     text: todo 
    }); 
    } 
} 

В коде выше, нет никакой гарантии, что TODO не будет добавлен в других, чем метод addTodo способов (например, вызывая todoService.todos.push({text: ''}) или даже путь перезаписи всего массива Todos).

Я всегда стараюсь, чтобы устранить эти возможности нарушения, что делает мои услуги в конечном итоге выглядит примерно так:

export class MyService { 
    private _myPrimitive: boolean; 
    get myPrimitive(): { return this._myPrimitive; } 

    private _myArray: Array<number>; 
    get myArray(): Array<number> { return this._myArray.splice(0); } 

    private _myObject: MyObject; 
    getMyObject(): MyObject { return JSON.parse(JSON.stringify(this._myObject)); } 

    private _onMyEvent = new Subject<Event>(); 
    get onMyEvent: Observable<Event> { return this._onMyEvent.asObservable(); } 
} 

Я не вижу этот стиль кодирования в любых приложениях Angular2. Это не просто уродливо, но и медленно, когда дело доходит до обнаружения изменений (стрельба JSON.parse(JSON.stringify(object) после того, как каждое событие «mousemove» очень дорогое), поэтому, очевидно, я делаю что-то неправильно.

Мой вопрос:

  1. Есть более изящные способы достижения только для чтения behaivour от внешнего MyService.

  2. Почему нет такой фокусировки на скрытии ненужной логики в Angular2, чем на других языках ООП, таких как Java/C#/PHP.

+0

Почему вы клонируете '_myObject'? Если они построены таким образом, то они должны быть неизменными, не так ли? –

+0

@ GünterZöchbauer Это правда, вы могли бы создать неизменяемый 'myObject', но иногда вам нужно хранить данные с открытыми полями.Также обратите внимание, что неизменяемость - это не то же самое, что доступно только для чтения (кто-то еще может перезаписать «myObject»). Клонируя это, я делаю простую защитную копию (http://www.javapractices.com/topic/TopicAction.do?Id=15), потому что я не хочу, чтобы она была модифицирована извне. Таким образом, объект не будет изменен через общедоступные поля/методы. –

+0

Вы можете использовать сборщики, где классы разрешают только модифицировать с помощью этого построителя. Только когда у вас есть ссылка на этот строитель, вы можете обновлять свойства. Если у вас много таких классов, удобно использовать генерацию кода для таких классов со сборщиками. –

ответ

1

Причина, по которой у нас есть геттер/сеттер для свойств, является принципом открытого/закрытого ООП. Например, в Java У меня есть класс Student, как показано ниже:

class Student { 
    public: 
    int age; 
} 

Если я обнажить возраст как открытый член, как это. Позже, если есть запрос на добавление ограничения, возраст которого должен быть менее 100. Я должен искать всю свою программу, чтобы проверить назначение возраста.

В машинописном вы можете написать так:

class Student { 
    age: number 
} 

Позже вы можете изменить только класс Student путем добавления геттер или сеттера.

class Student { 
    get age() { 
    } 
    set age(value: number) { 
    } 
} 

И когда вы используете student.age = 15 он позвонит установить возраст. Не нужно менять внешний код. Поэтому по умолчанию вам не нужно писать getter/setter.

По вопросам ваших ответов:

  1. Вы можете использовать общественный получить и частный набор.

  2. Это мнение не факт. Вы всегда можете установить член под частным, чтобы скрыть его извне.

+0

Извините, но мне все еще нужно уточнить ваш первый ответ. Как вы можете видеть в моем вопросе, я уже использую публичные геттеры с частными полями в своем коде, но это делает их только для чтения, когда они являются примитивами. Если я возвращаю объект с помощью getter, я возвращаю ссылку, поэтому объект все равно может быть мутирован через общедоступные поля/методы, поэтому он не доступен для чтения, а значит, клонирование в моем ответе. –

+0

Вы можете ссылаться на этот ответ, когда хотите клонировать объект: http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object-in-javascript В C#, Java, C++ вы должны сделать то же самое (клонирование). –

+0

Извините, но вы даже прочитали мой вопрос? Я уже использую наиболее эффективные методы клонирования, а также все, что вы предложили в своем ответе. См. Второй клип кода. –

Смежные вопросы