在OOP中,我被告知你的对象应该只通过吸气剂暴露他们的成员,不应该允许直接变异。
看一些Angular2应用程序,我总是看到这个概念受到侵犯。
export class TodoService {
todos: Array<TodoData> = [];
addTodo(todo: string) {
this.todos.push({
text: todo
});
}
}
在上面的代码中,不能保证不会以addTodo
方法之外的方式添加待办事项(例如调用todoService.todos.push({text: ''})
或甚至覆盖整个待办事项数组)。
我总是试图消除这些违规可能性,这使我的服务看起来与此类似:
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应用程序中看到这种编码风格。这不仅仅是丑陋的,而且在变换检测方面也很慢(在每次'mousemove'事件后非常昂贵地触发JSON.parse(JSON.stringify(object)
)所以很明显我做错了。
我的问题是:
是否有更优雅的方法可以从外部MyService
获得只读行为。
为什么在Angular2中隐藏不必要的逻辑没有像其他OOP语言(如Java / C#/ PHP)那样隐藏。
答案 0 :(得分:2)
我们为属性设置getter / setter的原因是OOP Open / Close原则。例如在Java中,我有一个类Student,如下所示:
class Student {
public:
int age;
}
如果我把这个年龄公之于众。稍后如果有要求添加年龄应小于100的约束,我必须搜索我的所有程序以检查年龄分配。
在Typescript中,您可以这样写:
class Student {
age: number
}
稍后您可以通过添加getter或setter来修改Student类。
class Student {
get age() {
}
set age(value: number) {
}
}
当你使用student.age = 15
时,它会调用set age。无需更改外部代码。因此,默认情况下,您不需要编写getter / setter。
如果对你的答案有疑问:
您可以使用公开获取和私有设置。
这种观点不是事实。您始终可以在私人下设置成员以将其从外部隐藏。