Pro typescript.ch03.Object Orientation in TypeScript
2
https://en.wikipedia.org/wiki/Object-oriented_programming
https://ko.wikipedia.org/wiki/객체_지향_프로그래밍
https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
https://en.wikipedia.org/wiki/This_(computer_programming)#Open_recursion
https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
https://en.wikipedia.org/wiki/Delegation_(computing)
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
Ch.01
5
 Combination of recursion and late binding
override 아니에요 ?
 No, no, no. Recursion and late binding.
그래도 그냥 함수 override인데…
6
interface FileItem {
path: string;
contents: string[];
}
class FileReader {
getFiles(path: string, depth: number = 0) {
var fileTree = [];
var files = fs.readdirSync(path);
for (var i = 0; i < files.length; i++) {
var file = files[i];
var stats = fs.statSync(file);
var fileItem;
if (stats.isDirectory()) {
// Add directory and contents
fileItem = {
path: file,
contents: this.getFiles(file, (depth + 1))
};
} else {
// Add file
fileItem = {
path: file,
contents: [] };
}
fileTree.push(fileItem);
}
return fileTree;
}
}
class LimitedFileReader extends FileReader {
constructor(public maxDepth: number) {
super();
}
getFiles(path: string, depth = 0) {
if (depth > this.maxDepth) {
return [];
}
return super.getFiles(path, depth);
}
}
// instatiating an instance of LimitedFileReader
var fileReader = new LimitedFileReader(1);
// results in only the top level, and one additional level being read
var files = fileReader.getFiles('path');
7
 Private 제한자를 사용해 변수, 함수를 외부로부터 숨김
 외부에 알리고 싶지 않은 것을 숨길 수 있음
 외부에서 몰라도 되는 것을 숨기는 것은 추상화(Abstraction)
추상화나 캡슐화나… 내가 보기엔 다 거서 건데…
8
class Totalizer {
private total = 0;
private taxRateFactor = 0.2;
addDonation(amount: number) {
if (amount <= 0) {
throw new Error('Donation exception');
}
var taxRebate = amount * this.taxRateFactor;
var totalDonation = amount + taxRebate;
this.total += totalDonation;
}
getAmountRaised() {
return this.total;
}
}
var totalizer = new Totalizer();
totalizer.addDonation(100.00);
var fundsRaised = totalizer.getAmountRaised();
// 120
console.log(fundsRaised);
9
 Wrapper class로 원래 class를 감싸는 형태
 상속관계 (is a)가 아닌 경우의 좋은 대안
 코드 재사용성 측면에 있어서 가장 유용한 개념
10
 Delegation : Has A
 Ingeritance : Is A
11
interface ControlPanel {
startAlarm(message: string): any;
}
interface Sensor {
check(): any;
}
class MasterControlPanel {
private sensors: Sensor[] = [];
constructor() {
// Instantiating the delegate HeatSensor
this.sensors.push(new HeatSensor(this));
}
start() {
for (var i= 0; i < this.sensors.length; i++) {
// Calling the delegate
this.sensors[i].check();
}
window.setTimeout(() => this.start(), 1000);
}
startAlarm(message: string) {
console.log('Alarm! ' + message);
}
}
class HeatSensor {
private upperLimit = 38;
private sensor = {
read: function() { return Math.floor(Math.random() * 100); }
};
constructor(private controlPanel: ControlPanel) {
}
check() {
if (this.sensor.read() > this.upperLimit) {
// Calling back to the wrapper
this.controlPanel.startAlarm('Overheating!');
}
}
}
var cp = new MasterControlPanel();
cp.start();
12
 같은 함수 시그너쳐를 여러가지로 다르게 구현
 Any structure with many similar structures
13
interface Vehicle {
moveTo(x: number, y: number);
}
class Car implements Vehicle {
moveTo(x: number, y: number) {
console.log('Driving to ' + x + ' ' + y);
}
}
class SportsCar extends Car {
}
class Airplane {
moveTo(x: number, y: number) {
console.log('Flying to ' + x + ' ' + y);
}
}
function navigate(vehicle: Vehicle) {
vehicle.moveTo(59.9436499, 10.7167959);
}
var airplane = new Airplane();
navigate(airplane);
var car = new SportsCar();
navigate(car);
Pro typescript.ch03.Object Orientation in TypeScript
15
16
http://blog.cleancoder.com
단일 책임의 원칙
클래스는 오직 한가지 작업만 수행해야 하며,
한 가지 이유에 의해서만 변경되어야 함.
17
class Movie {
private db: DataBase;
constructor(private title: string, private year: number) {
this.db = DataBase.connect('user:pw@mydb', ['movies']);
}
getTitle() {
return this.title + ' (' + this.year + ')';
}
save() {
this.db.movies.save({ title: this.title, year: this.year });
}
}
18
class Movie {
constructor(private title: string, private year: number) {
}
getTitle() {
return this.title + ' (' + this.year + ')';
}
}
class MovieRepository {
private db: DataBase;
constructor() {
this.db = DataBase.connect('user:pw@mydb', ['movies']);
}
save(movie: Movie) {
this.db.movies.save(JSON.stringify(movie));
}
}
// Movie
var movie = new Movie('The Internship', 2013);
// MovieRepository
var movieRepository = new MovieRepository();
movieRepository.save(movie);
19
개방/폐쇄 원칙
확장에 대해서는 개방적이어여 하고,
수정에 대해서는 폐쇄적이어야 한다.
20
class RewardPointsCalculator {
getPoints(transactionValue: number) {
// 4 points per whole dollar spent
return Math.floor(transactionValue) * 4;
}
}
class DoublePointsCalculator extends RewardPointsCalculator {
getPoints(transactionValue: number) {
var standardPoints = super.getPoints(transactionValue);
return standardPoints * 2;
}
}
var pointsCalculator = new DoublePointsCalculator();
alert(pointsCalculator.getPoints(100.99));
21
리스코프 치환 원칙
S가 T의 하위속성이라면 프로그램의 변경없이
T의 객체를 S로 교체(치환)할 수 있어야 한다.
Data Abstraction and Hireachy, 1998 - Babara Liskov
22
출처 : C#으로 배우는 적응형 코드
23
인터페이스 분리 원칙
인터페이스를 최대한 작게 만드는 것이
여러가지 기능을 하는 인터페이스 하나보다 더 좋다.
24
interface Printer {
copyDocument();
printDocument(document: Document);
stapleDocument(document: Document, tray: number);
}
interface Printer {
printDocument(document: Document);
}
interface Stapler {
stapleDocument(document: Document, tray: number);
}
interface Copier {
copyDocument();
}
class SimplePrinter implements Printer {
printDocument(document: Document) {
//...
}
}
class SuperPrinter implements Printer, Stapler, Copier {
printDocument(document: Document) {
//...
}
copyDocument() {
//...
}
stapleDocument(document: Document, tray: number) {
//...
}
}
25
의존성 역주입 원칙
직접적인 의존을 피하고,
인터페이스에 의존하라.
26
class LightSwitch {
private isOn = false;
constructor(private light: Light) {
}
onPress() {
if (this.isOn) {
this.light.switchOff();
this.isOn = false;
} else {
this.light.switchOn();
this.isOn = true;
}
}
}
interface LightSource {
switchOn();
switchOff();
}
class Light {
switchOn() {
//...
}
switchOff() {
//...
}
}
Pro typescript.ch03.Object Orientation in TypeScript
28
29
전략 패턴
30
추상 팩토리 패턴
31
interface WheelCleaning {
cleanWheels(): void;
}
class BasicWheelCleaning implements WheelCleaning {
cleanWheels() {
console.log('Soaping Wheel');
console.log('Brushing wheel');
}
}
class ExecutiveWheelCleaning extends
BasicWheelCleaning {
cleanWheels() {
super.cleanWheels();
console.log('Waxing Wheel');
console.log('Rinsing Wheel');
}
}
interface BodyCleaning {
cleanBody(): void;
}
class BasicBodyCleaning implements BodyCleaning {
cleanBody() {
console.log('Soaping car');
console.log('Rinsing Car');
}
}
class ExecutiveBodyCleaning extends BasicBodyCleaning
{
cleanBody() {
super.cleanBody();
console.log('Waxing car');
console.log('Blow drying car');
}
}
32
class CarWashProgram {
constructor(private washLevel: number) {
}
runWash() {
var wheelWash: WheelCleaning;
var bodyWash: BodyCleaning;
switch (this.washLevel) {
case 1:
wheelWash = new BasicWheelCleaning();
wheelWash.cleanWheels();
bodyWash = new BasicBodyCleaning();
bodyWash.cleanBody();
break;
case 2:
wheelWash = new BasicWheelCleaning();
wheelWash.cleanWheels();
bodyWash = new ExecutiveBodyCleaning();
bodyWash.cleanBody();
break;
case 3:
wheelWash = new ExecutiveWheelCleaning();
wheelWash.cleanWheels();
bodyWash = new ExecutiveBodyCleaning();
bodyWash.cleanBody();
break;
}
}
}
33
interface ValetFactory {
getWheelCleaning() : WheelCleaning;
getBodyCleaning() : BodyCleaning;
}
class SilverWashFactory implements ValetFactory {
getWheelCleaning() {
return new BasicWheelCleaning();
}
getBodyCleaning() {
return new ExecutiveBodyCleaning();
}
}
class GoldWashFactory implements ValetFactory {
getWheelCleaning() {
return new ExecutiveWheelCleaning();
}
getBodyCleaning() {
return new ExecutiveBodyCleaning();
}
}
class BronzeWashFactory implements ValetFactory {
getWheelCleaning() {
return new BasicWheelCleaning();
}
getBodyCleaning() {
return new BasicBodyCleaning();
}
}
34
class CarWashProgram {
constructor(private cleaningFactory: ValetFactory) {
}
runWash() {
var wheelWash = this.cleaningFactory.getWheelCleaning();
wheelWash.cleanWheels();
var bodyWash = this.cleaningFactory.getBodyCleaning();
bodyWash.cleanBody();
}
}
Pro typescript.ch03.Object Orientation in TypeScript
36
37
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
if (name !== 'constructor') {
derivedCtor.prototype[name] = baseCtor.prototype[name];
}
})
});
}
38
class Sings {
sing() {
console.log('Singing');
}
}
class Dances {
dance() {
console.log('Dancing');
}
}
class Acts {
act() {
console.log('Acting');
}
}
39
class Actor implements Acts {
act: () => void;
}
applyMixins(Actor, [Acts]);
class AllRounder implements Acts, Dances, Sings {
act: () => void;
dance: () => void;
sing: () => void;
}
applyMixins(AllRounder, [Acts, Dances, Sings]);
40
var actor = new Actor();
actor.act();
var allRounder = new AllRounder();
allRounder.act();
allRounder.dance();
allRounder.sing();
41
42
43
class Acts {
public message = 'Acting';
act() {
console.log(this.message);
}
}
class Actor implements Acts {
public message: string;
act: () => void;
}
applyMixins(Actor, [Acts]);
var actor = new Actor();
// Logs 'undefined', not 'Acting'
actor.act();
class Acts {
public static message = 'Acting';
act() {
alert(Acts.message);
}
}
Pro typescript.ch03.Object Orientation in TypeScript
45
https://github.com/DevStarSJ/Study/blob/master/Blog/Front-end/TypeScript/03.ObjectOrientationInTypeScript.md

More Related Content

PDF
Welcome to Modern C++
PDF
Алексей Кутумов, Coroutines everywhere
PPTX
Алексей Кутумов, Вектор с нуля
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
PDF
Qt Rest Server
PPTX
Lexical environment in ecma 262 5
PPT
Евгений Крутько, Многопоточные вычисления, современный подход.
PPTX
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Welcome to Modern C++
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Вектор с нуля
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
Qt Rest Server
Lexical environment in ecma 262 5
Евгений Крутько, Многопоточные вычисления, современный подход.
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it

What's hot (20)

PPTX
How Data Flow analysis works in a static code analyzer
PDF
PVS-Studio in 2021 - Error Examples
PPTX
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
PDF
The mighty js_function
PDF
Joel Falcou, Boost.SIMD
PDF
Modern C++ Concurrency API
PPT
شرح مقرر البرمجة 2 لغة جافا - الوحدة الثالثة
PDF
C++ game development with oxygine
PPT
شرح مقرر البرمجة 2 لغة جافا - الوحدة الرابعة
PPTX
Node.js System: The Landing
PDF
Asterisk: PVS-Studio Takes Up Telephony
PPTX
Дмитрий Нестерук, Паттерны проектирования в XXI веке
PDF
Flashback, el primer malware masivo de sistemas Mac
PDF
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
PDF
Коварный code type ITGM #9
PPTX
Дмитрий Демчук. Кроссплатформенный краш-репорт
PDF
Javascript scoping
PDF
Polymorphism
PDF
C++ L08-Classes Part1
PDF
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
How Data Flow analysis works in a static code analyzer
PVS-Studio in 2021 - Error Examples
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
The mighty js_function
Joel Falcou, Boost.SIMD
Modern C++ Concurrency API
شرح مقرر البرمجة 2 لغة جافا - الوحدة الثالثة
C++ game development with oxygine
شرح مقرر البرمجة 2 لغة جافا - الوحدة الرابعة
Node.js System: The Landing
Asterisk: PVS-Studio Takes Up Telephony
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Flashback, el primer malware masivo de sistemas Mac
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Коварный code type ITGM #9
Дмитрий Демчук. Кроссплатформенный краш-репорт
Javascript scoping
Polymorphism
C++ L08-Classes Part1
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
Ad

Similar to Pro typescript.ch03.Object Orientation in TypeScript (20)

PDF
Letswift19-clean-architecture
PDF
Hello Swift Final 5/5 - Structures and Classes
PPTX
Design patterns
PPTX
OOP in JavaScript
PDF
Writing native bindings to node.js in C++
PDF
Flow control in node.js
PDF
Swift Basics
PDF
Kotlin @ Coupang Backend 2017
PDF
Design for Testability
PPT
닷넷 개발자를 위한 패턴이야기
PDF
Cooking your Ravioli "al dente" with Hexagonal Architecture
PDF
Why Typescript with Clean Architecture
PDF
JavaScript Abstraction
PPTX
Ecma script6
PPT
Refactoring bad codesmell
PPTX
Type script by Howard
PPT
How much do we know about Object-Oriented Programming?
PDF
Design patterns in the 21st Century
PPTX
Creational pattern 2
Letswift19-clean-architecture
Hello Swift Final 5/5 - Structures and Classes
Design patterns
OOP in JavaScript
Writing native bindings to node.js in C++
Flow control in node.js
Swift Basics
Kotlin @ Coupang Backend 2017
Design for Testability
닷넷 개발자를 위한 패턴이야기
Cooking your Ravioli "al dente" with Hexagonal Architecture
Why Typescript with Clean Architecture
JavaScript Abstraction
Ecma script6
Refactoring bad codesmell
Type script by Howard
How much do we know about Object-Oriented Programming?
Design patterns in the 21st Century
Creational pattern 2
Ad

More from Seok-joon Yun (20)

PDF
Retrospective.2020 03
PDF
Sprint & Jira
PPTX
Eks.introduce.v2
PDF
Eks.introduce
PDF
AWS DEV DAY SEOUL 2017 Buliding Serverless Web App - 직방 Image Converter
PDF
아파트 시세,어쩌다 머신러닝까지
PPTX
Pro typescript.ch07.Exception, Memory, Performance
PPTX
Doing math with python.ch07
PPTX
Doing math with python.ch06
PPTX
Doing math with python.ch05
PPTX
Doing math with python.ch04
PPTX
Doing math with python.ch03
PPTX
Doing mathwithpython.ch02
PPTX
Doing math with python.ch01
PDF
C++ Concurrency in Action 9-2 Interrupting threads
PDF
[2015-07-20-윤석준] Oracle 성능 관리 2
PDF
[2015-07-10-윤석준] Oracle 성능 관리 & v$sysstat
PDF
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
PDF
오렌지6.0 교육자료
PDF
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
Retrospective.2020 03
Sprint & Jira
Eks.introduce.v2
Eks.introduce
AWS DEV DAY SEOUL 2017 Buliding Serverless Web App - 직방 Image Converter
아파트 시세,어쩌다 머신러닝까지
Pro typescript.ch07.Exception, Memory, Performance
Doing math with python.ch07
Doing math with python.ch06
Doing math with python.ch05
Doing math with python.ch04
Doing math with python.ch03
Doing mathwithpython.ch02
Doing math with python.ch01
C++ Concurrency in Action 9-2 Interrupting threads
[2015-07-20-윤석준] Oracle 성능 관리 2
[2015-07-10-윤석준] Oracle 성능 관리 & v$sysstat
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
오렌지6.0 교육자료
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3

Recently uploaded (20)

PDF
How Tridens DevSecOps Ensures Compliance, Security, and Agility
PDF
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
PDF
Microsoft Office 365 Crack Download Free
PDF
Cloud Native Aachen Meetup - Aug 21, 2025
PPTX
Introduction to Windows Operating System
PDF
AI Guide for Business Growth - Arna Softech
PDF
CapCut PRO for PC Crack New Download (Fully Activated 2025)
PDF
Visual explanation of Dijkstra's Algorithm using Python
PPTX
Cybersecurity: Protecting the Digital World
PDF
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
PDF
Practical Indispensable Project Management Tips for Delivering Successful Exp...
PDF
DNT Brochure 2025 – ISV Solutions @ D365
PPTX
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
DOCX
How to Use SharePoint as an ISO-Compliant Document Management System
DOC
UTEP毕业证学历认证,宾夕法尼亚克拉里恩大学毕业证未毕业
PDF
CCleaner 6.39.11548 Crack 2025 License Key
PDF
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
PDF
MiniTool Power Data Recovery 12.6 Crack + Portable (Latest Version 2025)
PPTX
Computer Software - Technology and Livelihood Education
PDF
MCP Security Tutorial - Beginner to Advanced
How Tridens DevSecOps Ensures Compliance, Security, and Agility
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
Microsoft Office 365 Crack Download Free
Cloud Native Aachen Meetup - Aug 21, 2025
Introduction to Windows Operating System
AI Guide for Business Growth - Arna Softech
CapCut PRO for PC Crack New Download (Fully Activated 2025)
Visual explanation of Dijkstra's Algorithm using Python
Cybersecurity: Protecting the Digital World
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
Practical Indispensable Project Management Tips for Delivering Successful Exp...
DNT Brochure 2025 – ISV Solutions @ D365
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
How to Use SharePoint as an ISO-Compliant Document Management System
UTEP毕业证学历认证,宾夕法尼亚克拉里恩大学毕业证未毕业
CCleaner 6.39.11548 Crack 2025 License Key
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
MiniTool Power Data Recovery 12.6 Crack + Portable (Latest Version 2025)
Computer Software - Technology and Livelihood Education
MCP Security Tutorial - Beginner to Advanced

Pro typescript.ch03.Object Orientation in TypeScript

  • 2. 2
  • 5. 5  Combination of recursion and late binding override 아니에요 ?  No, no, no. Recursion and late binding. 그래도 그냥 함수 override인데…
  • 6. 6 interface FileItem { path: string; contents: string[]; } class FileReader { getFiles(path: string, depth: number = 0) { var fileTree = []; var files = fs.readdirSync(path); for (var i = 0; i < files.length; i++) { var file = files[i]; var stats = fs.statSync(file); var fileItem; if (stats.isDirectory()) { // Add directory and contents fileItem = { path: file, contents: this.getFiles(file, (depth + 1)) }; } else { // Add file fileItem = { path: file, contents: [] }; } fileTree.push(fileItem); } return fileTree; } } class LimitedFileReader extends FileReader { constructor(public maxDepth: number) { super(); } getFiles(path: string, depth = 0) { if (depth > this.maxDepth) { return []; } return super.getFiles(path, depth); } } // instatiating an instance of LimitedFileReader var fileReader = new LimitedFileReader(1); // results in only the top level, and one additional level being read var files = fileReader.getFiles('path');
  • 7. 7  Private 제한자를 사용해 변수, 함수를 외부로부터 숨김  외부에 알리고 싶지 않은 것을 숨길 수 있음  외부에서 몰라도 되는 것을 숨기는 것은 추상화(Abstraction) 추상화나 캡슐화나… 내가 보기엔 다 거서 건데…
  • 8. 8 class Totalizer { private total = 0; private taxRateFactor = 0.2; addDonation(amount: number) { if (amount <= 0) { throw new Error('Donation exception'); } var taxRebate = amount * this.taxRateFactor; var totalDonation = amount + taxRebate; this.total += totalDonation; } getAmountRaised() { return this.total; } } var totalizer = new Totalizer(); totalizer.addDonation(100.00); var fundsRaised = totalizer.getAmountRaised(); // 120 console.log(fundsRaised);
  • 9. 9  Wrapper class로 원래 class를 감싸는 형태  상속관계 (is a)가 아닌 경우의 좋은 대안  코드 재사용성 측면에 있어서 가장 유용한 개념
  • 10. 10  Delegation : Has A  Ingeritance : Is A
  • 11. 11 interface ControlPanel { startAlarm(message: string): any; } interface Sensor { check(): any; } class MasterControlPanel { private sensors: Sensor[] = []; constructor() { // Instantiating the delegate HeatSensor this.sensors.push(new HeatSensor(this)); } start() { for (var i= 0; i < this.sensors.length; i++) { // Calling the delegate this.sensors[i].check(); } window.setTimeout(() => this.start(), 1000); } startAlarm(message: string) { console.log('Alarm! ' + message); } } class HeatSensor { private upperLimit = 38; private sensor = { read: function() { return Math.floor(Math.random() * 100); } }; constructor(private controlPanel: ControlPanel) { } check() { if (this.sensor.read() > this.upperLimit) { // Calling back to the wrapper this.controlPanel.startAlarm('Overheating!'); } } } var cp = new MasterControlPanel(); cp.start();
  • 12. 12  같은 함수 시그너쳐를 여러가지로 다르게 구현  Any structure with many similar structures
  • 13. 13 interface Vehicle { moveTo(x: number, y: number); } class Car implements Vehicle { moveTo(x: number, y: number) { console.log('Driving to ' + x + ' ' + y); } } class SportsCar extends Car { } class Airplane { moveTo(x: number, y: number) { console.log('Flying to ' + x + ' ' + y); } } function navigate(vehicle: Vehicle) { vehicle.moveTo(59.9436499, 10.7167959); } var airplane = new Airplane(); navigate(airplane); var car = new SportsCar(); navigate(car);
  • 15. 15
  • 16. 16 http://blog.cleancoder.com 단일 책임의 원칙 클래스는 오직 한가지 작업만 수행해야 하며, 한 가지 이유에 의해서만 변경되어야 함.
  • 17. 17 class Movie { private db: DataBase; constructor(private title: string, private year: number) { this.db = DataBase.connect('user:pw@mydb', ['movies']); } getTitle() { return this.title + ' (' + this.year + ')'; } save() { this.db.movies.save({ title: this.title, year: this.year }); } }
  • 18. 18 class Movie { constructor(private title: string, private year: number) { } getTitle() { return this.title + ' (' + this.year + ')'; } } class MovieRepository { private db: DataBase; constructor() { this.db = DataBase.connect('user:pw@mydb', ['movies']); } save(movie: Movie) { this.db.movies.save(JSON.stringify(movie)); } } // Movie var movie = new Movie('The Internship', 2013); // MovieRepository var movieRepository = new MovieRepository(); movieRepository.save(movie);
  • 19. 19 개방/폐쇄 원칙 확장에 대해서는 개방적이어여 하고, 수정에 대해서는 폐쇄적이어야 한다.
  • 20. 20 class RewardPointsCalculator { getPoints(transactionValue: number) { // 4 points per whole dollar spent return Math.floor(transactionValue) * 4; } } class DoublePointsCalculator extends RewardPointsCalculator { getPoints(transactionValue: number) { var standardPoints = super.getPoints(transactionValue); return standardPoints * 2; } } var pointsCalculator = new DoublePointsCalculator(); alert(pointsCalculator.getPoints(100.99));
  • 21. 21 리스코프 치환 원칙 S가 T의 하위속성이라면 프로그램의 변경없이 T의 객체를 S로 교체(치환)할 수 있어야 한다. Data Abstraction and Hireachy, 1998 - Babara Liskov
  • 22. 22 출처 : C#으로 배우는 적응형 코드
  • 23. 23 인터페이스 분리 원칙 인터페이스를 최대한 작게 만드는 것이 여러가지 기능을 하는 인터페이스 하나보다 더 좋다.
  • 24. 24 interface Printer { copyDocument(); printDocument(document: Document); stapleDocument(document: Document, tray: number); } interface Printer { printDocument(document: Document); } interface Stapler { stapleDocument(document: Document, tray: number); } interface Copier { copyDocument(); } class SimplePrinter implements Printer { printDocument(document: Document) { //... } } class SuperPrinter implements Printer, Stapler, Copier { printDocument(document: Document) { //... } copyDocument() { //... } stapleDocument(document: Document, tray: number) { //... } }
  • 25. 25 의존성 역주입 원칙 직접적인 의존을 피하고, 인터페이스에 의존하라.
  • 26. 26 class LightSwitch { private isOn = false; constructor(private light: Light) { } onPress() { if (this.isOn) { this.light.switchOff(); this.isOn = false; } else { this.light.switchOn(); this.isOn = true; } } } interface LightSource { switchOn(); switchOff(); } class Light { switchOn() { //... } switchOff() { //... } }
  • 28. 28
  • 31. 31 interface WheelCleaning { cleanWheels(): void; } class BasicWheelCleaning implements WheelCleaning { cleanWheels() { console.log('Soaping Wheel'); console.log('Brushing wheel'); } } class ExecutiveWheelCleaning extends BasicWheelCleaning { cleanWheels() { super.cleanWheels(); console.log('Waxing Wheel'); console.log('Rinsing Wheel'); } } interface BodyCleaning { cleanBody(): void; } class BasicBodyCleaning implements BodyCleaning { cleanBody() { console.log('Soaping car'); console.log('Rinsing Car'); } } class ExecutiveBodyCleaning extends BasicBodyCleaning { cleanBody() { super.cleanBody(); console.log('Waxing car'); console.log('Blow drying car'); } }
  • 32. 32 class CarWashProgram { constructor(private washLevel: number) { } runWash() { var wheelWash: WheelCleaning; var bodyWash: BodyCleaning; switch (this.washLevel) { case 1: wheelWash = new BasicWheelCleaning(); wheelWash.cleanWheels(); bodyWash = new BasicBodyCleaning(); bodyWash.cleanBody(); break; case 2: wheelWash = new BasicWheelCleaning(); wheelWash.cleanWheels(); bodyWash = new ExecutiveBodyCleaning(); bodyWash.cleanBody(); break; case 3: wheelWash = new ExecutiveWheelCleaning(); wheelWash.cleanWheels(); bodyWash = new ExecutiveBodyCleaning(); bodyWash.cleanBody(); break; } } }
  • 33. 33 interface ValetFactory { getWheelCleaning() : WheelCleaning; getBodyCleaning() : BodyCleaning; } class SilverWashFactory implements ValetFactory { getWheelCleaning() { return new BasicWheelCleaning(); } getBodyCleaning() { return new ExecutiveBodyCleaning(); } } class GoldWashFactory implements ValetFactory { getWheelCleaning() { return new ExecutiveWheelCleaning(); } getBodyCleaning() { return new ExecutiveBodyCleaning(); } } class BronzeWashFactory implements ValetFactory { getWheelCleaning() { return new BasicWheelCleaning(); } getBodyCleaning() { return new BasicBodyCleaning(); } }
  • 34. 34 class CarWashProgram { constructor(private cleaningFactory: ValetFactory) { } runWash() { var wheelWash = this.cleaningFactory.getWheelCleaning(); wheelWash.cleanWheels(); var bodyWash = this.cleaningFactory.getBodyCleaning(); bodyWash.cleanBody(); } }
  • 36. 36
  • 37. 37 function applyMixins(derivedCtor: any, baseCtors: any[]) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { if (name !== 'constructor') { derivedCtor.prototype[name] = baseCtor.prototype[name]; } }) }); }
  • 38. 38 class Sings { sing() { console.log('Singing'); } } class Dances { dance() { console.log('Dancing'); } } class Acts { act() { console.log('Acting'); } }
  • 39. 39 class Actor implements Acts { act: () => void; } applyMixins(Actor, [Acts]); class AllRounder implements Acts, Dances, Sings { act: () => void; dance: () => void; sing: () => void; } applyMixins(AllRounder, [Acts, Dances, Sings]);
  • 40. 40 var actor = new Actor(); actor.act(); var allRounder = new AllRounder(); allRounder.act(); allRounder.dance(); allRounder.sing();
  • 41. 41
  • 42. 42
  • 43. 43 class Acts { public message = 'Acting'; act() { console.log(this.message); } } class Actor implements Acts { public message: string; act: () => void; } applyMixins(Actor, [Acts]); var actor = new Actor(); // Logs 'undefined', not 'Acting' actor.act(); class Acts { public static message = 'Acting'; act() { alert(Acts.message); } }
  • 45. 45