객체 지향 프로그래밍
21994 단어 oopprogrammingbeginnersjavascript
내가 이해한 객체지향 프로그래밍(OOP)은 모든 데이터와 연산을 하나의 객체/클래스로 그룹화하고 적절하게 그룹화해야 하는 코딩 방식이라고 이해한다.
쉬운 것 같죠? 그러나 실제로는 때때로 데이터와 작업을 그룹화하기 어렵고 잘못된 개체에 쉽게 넣을 수 있기 때문에 매우 잘 계획되어야 합니다. 여기에서 잘 디자인된 개체를 만들기 위한 프로그래머의 기술이 필요하며 이를 달성하는 방법에 대한 몇 가지 기본 정보를 제공하겠습니다.
먼저 다음에 대해 이야기합니다.
응집력과 결합
Robert C. Martin(a.k.a 엉클 밥)의 S.O.L.I.D 원칙에는 응집력과 결합의 개념이 있습니다.
응집력
응집력은 데이터와 작업이 얼마나 잘 그룹화 또는 관련되어 있는지를 나타내는 척도입니다. 응집력이 높으면 잘 그룹화되어 있고 그렇지 않으면 응집력이 낮습니다. (목표는 높은 응집력을 갖는 것입니다).
커플 링
결합은 개체 간의 종속성 측정입니다. 다른 객체에 대한 의존도가 높은 객체는 결합도가 높습니다. 결합은 불가피하지만 추상화 또는 인터페이스를 사용하여 결합을 줄이도록 설계할 수 있습니다. (목표는 더 적은 수의 연결된 객체를 갖는 것입니다).
OOP의 4가지 기둥
계승
기존 객체를 확장하거나 합성하여 재사용하고 싶을 때입니다. 보다 일반적인 객체를 생성하고 보다 구체적인 객체가 이러한 일반 객체를 확장하도록 할 수 있습니다.
// generic object
class Tag {
className: string;
id: string;
constructor(className: string, id: string) {
this.className = className;
this.id = id;
}
display() { ... }
}
// inheritance
class AnchorTag extends Tag {
href: string;
constructor(className: string, id: string, href: string) {
super(className, id);
this.href = href;
}
// override
display() { ... }
// adding feature
onClick() { ... }
}
구성(상속보다 우선)
개체의 계층 구조가 커지면 상속을 추적하기 어렵습니다. 이런 일이 발생하면 어떤 필드와 작업이 있는지 알기 위해 개체의 전체 부모를 살펴봐야 합니다. (이는 또한 상위 개체에 밀접하게 연결되어 있음을 의미합니다). 구성을 사용하면 인터페이스로 개체를 참조하여 결합을 줄일 수 있습니다.
// generic object
class Tag {
className: string;
id: string;
constructor(className: string, id: string) {
this.className = className;
this.id = id;
}
display() { ... }
}
// inheritance
class AnchorTag {
href: string;
tag: Tag; // composing the Tag object
constructor(className: string, id: string, href: string) {
this.tag = new Tag(className; id); // this can be improved by providing factory method that returns interface to reduce coupling.
this.href = href;
}
// use Tag display method
display() {
this.tag.display();
}
// adding feature
onClick() { ... }
}
캡슐화
잘못된 상태를 할당하고 데이터를 가져온 위치를 숨기지 않도록 데이터를 보호하는 것입니다. 자바스크립트에서 캡슐화를 달성하려면 객체를 함수로 래핑해야 합니다.
const user = (name) => {
let nameField = name;
return {
setName: (newName) => {
/*
* validate input to protect
* invalid state for nameField
*/
nameField = newName;
},
getName: () => {
/*
* hide how nameField retrieved
*/
return nameField;
}
}
}
const tom = user("tom");
// tom.nameField = 123897 is now protected
console.log(tom.getName()) // tom
tom.setName('thomas');
console.log(tom.getName()) // thom
이는 인터페이스를 사용하고 접근자만 노출함으로써 typescript로 달성할 수도 있습니다.
interface IUser {
setName(newName: string);
getName(): string;
}
class User implements IUser {
name: string
constructor(name: string) {
// validation
this.name = name;
}
setName(newName: string) {
// validation
this.name = newName;
}
getName(): string {
// hide how it was retrieved
return this.name;
}
}
// factory function
const createUser = (name: string): IUser {
return new User(name);
}
const user = createUser('tom');
// user.name error name is not defined on interface.
user.setName('thom');
user.getName(); // thom
추출
소비자에게 객체의 복잡성 또는 관련 없는 구현을 숨기는 것입니다. 프로그래머로서 우리 시간의 80%는 코드를 읽고 나머지는 새로운 것을 작성하고, 개선하고, 버그를 수정하는 것입니다. 따라서 읽기에 소요되는 시간을 줄이기 위해 구현을 숨기는 것이 좋습니다. 추상화는 또한 구체적인 구현에 의존하지 않기 때문에 결합을 줄입니다.
interface IPlayer {
play();
}
// Abstracted;
class Player implements IPlayer {
file: IPlayer;
constructor(f: IPlayer) {
this.file = f;
}
play() { // abstraction of play();
this.file.play();
}
}
// concrete class
class Mp3 implements IPlayer {
play() {
// do stuffs here.
}
}
// concrete class
class Mp4 implements IPlayer {
play() {
// do stuffs here
}
}
// factory function
const createFile(file: string): IPlayer {
switch(file) {
case 'mp3':
return new Mp3();
case 'mp4':
return new Mp4();
}
}
// client
const player = new Player(createFile('mp3'));
player.play();
추상화는 객체만을 위한 것이 아니라 모든 곳에서 찾을 수 있습니다.
추상화가 없습니다.
// consumer
if (15 > 10 && 15 < 20)) {
console.log('I inside of range');
}
추상화.
// Abstraction
const initRange = (value) => (min, max) => value > min && value < max;
const rangeOf = initRange(15);
// Consumer
// Abstracted
if (rangeOf(10, 20)) {
console.log('I inside of range');
}
다형성
개체 또는 정보를 전달하여 여러 구현을 수행할 수 있습니다.
interface Action {
act();
}
class People {
action: Action;
constructor(action: Action) {
this.action = action;
}
setAction(action: Action) {
this.action = action;
}
perform() {
this.action.act();
}
}
class Sing implements Action {
act() {
console.log('Singing');
}
}
class Dance implements Action {
act() {
console.log('Dancing');
}
}
const sarah = new People(new Sing())
sarah.act(); // Singing
sarah.setAction(new Dance());
sarah.act(); // Dancing
디자인 패턴 배우기
객체 지향 프로그래밍은 때때로 이해하기 어렵지만 디자인 패턴은 더 많은 아이디어를 가질 수 있고 사용 사례를 기반으로 각 기둥이 얼마나 유용한지 이해할 수 있는 시나리오를 기반으로 하기 때문에 디자인 패턴을 배우고 읽는 것이 좋습니다.
고맙습니다
제 블로그를 끝까지 읽어주셔서 감사합니다. 감사합니다. 제 이메일을 통해 제 글을 개선할 수 있도록 언제든지 연락주세요. 많은 것을 배웠기를 바랍니다. ;)
나를 따르라
짧은 아이디어를 게시하고 매일 배운 내용을 공유하는 저를 팔로우하세요.
Reference
이 문제에 관하여(객체 지향 프로그래밍), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/vindecodex/object-oriented-programming-172o텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)