Про "Функциональную зависть"
"Функциональная зависть" (Functionality Envy) - это термин из области объектно-ориентированного программирования, описывающий ситуацию, когда метод одного класса чрезмерно использует данные другого класса. Это говорит о том, что метод "завидует" другому классу, желая использовать его данные и функциональность, вместо того чтобы выполнять задачи, которые он должен выполнять внутри своего класса.
Давайте рассмотрим пример этой проблемы в контексте Angular и TypeScript.
Представим, что у нас есть два класса: UserService и UserComponent. UserService управляет данными пользователя, а UserComponent отвечает за отображение этих данных.
Пример кода с функциональной завистью:
// user.service.ts
export class UserService {
private user = {
id: 1,
name: 'John Doe',
email: 'john.doe@example.com'
};
getUser() {
return this.user;
}
getUserName() {
return this.user.name;
}
getUserEmail() {
return this.user.email;
}
}
// user.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-user',
template: `
<div>
<h1>{{ userName }}</h1>
<p>{{ userEmail }}</p>
</div>
`
})
export class UserComponent implements OnInit {
userName: string;
userEmail: string;
constructor(private userService: UserService) {}
ngOnInit() {
const user = this.userService.getUser();
this.userName = user.name;
this.userEmail = user.email;
}
}
В этом примере UserComponent напрямую обращается к данным пользователя через метод getUser в UserService и использует их для своих нужд. Это типичный пример функциональной зависти, так как UserComponent чрезмерно зависит от структуры данных, предоставляемых UserService.
// user.service.ts
export class UserService {
private user = {
id: 1,
name: 'John Doe',
email: 'john.doe@example.com'
};
getUserName() {
return this.user.name;
}
getUserEmail() {
return this.user.email;
}
}
// user.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-user',
template: `
<div>
<h1>{{ userName }}</h1>
<p>{{ userEmail }}</p>
</div>
`
})
export class UserComponent implements OnInit {
userName: string;
userEmail: string;
constructor(private userService: UserService) {}
ngOnInit() {
this.userName = this.userService.getUserName();
this.userEmail = this.userService.getUserEmail();
}
}
Теперь UserComponent больше не зависит от внутренней структуры данных пользователя. Вместо этого он использует методы getUserName и getUserEmail, предоставляемые UserService. Это улучшает инкапсуляцию и уменьшает зависимость между компонентами, решая проблему функциональной зависти.