SlideShare a Scribd company logo
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

What's hot (20)

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

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

PDF
Letswift19-clean-architecture
Jung Kim
 
PDF
Hello Swift Final 5/5 - Structures and Classes
Cody Yun
 
PPTX
Design patterns
Luis Goldster
 
PPTX
OOP in JavaScript
Eyal Vardi
 
PDF
Writing native bindings to node.js in C++
nsm.nikhil
 
PDF
Flow control in node.js
iamhjoo (송형주)
 
PDF
Swift Basics
Jong-Hyun Kim
 
PDF
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
PDF
Design for Testability
Stanislav Tiurikov
 
PPT
닷넷 개발자를 위한 패턴이야기
YoungSu Son
 
PDF
Cooking your Ravioli "al dente" with Hexagonal Architecture
Jeroen Rosenberg
 
PDF
Why Typescript with Clean Architecture
유진 정
 
PDF
JavaScript Abstraction
☆ Milan Adamovsky ☆
 
PPTX
Ecma script6
동욱 박
 
PPT
Refactoring bad codesmell
hyunglak kim
 
PPTX
Type script by Howard
LearningTech
 
PPT
How much do we know about Object-Oriented Programming?
Sandro Mancuso
 
PDF
Design patterns in the 21st Century
Samir Talwar
 
PPTX
Creational pattern 2
Naga Muruga
 
Letswift19-clean-architecture
Jung Kim
 
Hello Swift Final 5/5 - Structures and Classes
Cody Yun
 
Design patterns
Luis Goldster
 
OOP in JavaScript
Eyal Vardi
 
Writing native bindings to node.js in C++
nsm.nikhil
 
Flow control in node.js
iamhjoo (송형주)
 
Swift Basics
Jong-Hyun Kim
 
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
Design for Testability
Stanislav Tiurikov
 
닷넷 개발자를 위한 패턴이야기
YoungSu Son
 
Cooking your Ravioli "al dente" with Hexagonal Architecture
Jeroen Rosenberg
 
Why Typescript with Clean Architecture
유진 정
 
JavaScript Abstraction
☆ Milan Adamovsky ☆
 
Ecma script6
동욱 박
 
Refactoring bad codesmell
hyunglak kim
 
Type script by Howard
LearningTech
 
How much do we know about Object-Oriented Programming?
Sandro Mancuso
 
Design patterns in the 21st Century
Samir Talwar
 
Creational pattern 2
Naga Muruga
 
Ad

More from Seok-joon Yun (20)

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

Recently uploaded (20)

PPTX
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
PDF
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
PPTX
IObit Uninstaller Pro 14.3.1.8 Crack Free Download 2025
sdfger qwerty
 
PDF
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
PPTX
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
PPTX
arctitecture application system design os dsa
za241967
 
PPTX
IDM Crack with Internet Download Manager 6.42 Build 41 [Latest 2025]
pcprocore
 
PDF
AI Software Development Process, Strategies and Challenges
Net-Craft.com
 
PDF
Automated Test Case Repair Using Language Models
Lionel Briand
 
PPTX
IObit Driver Booster Pro 12.4-12.5 license keys 2025-2026
chaudhryakashoo065
 
PPTX
For my supp to finally picking supp that work
necas19388
 
PDF
Code Once; Run Everywhere - A Beginner’s Journey with React Native
Hasitha Walpola
 
PDF
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
PDF
AWS Consulting Services: Empowering Digital Transformation with Nlineaxis
Nlineaxis IT Solutions Pvt Ltd
 
PDF
The Rise of Sustainable Mobile App Solutions by New York Development Firms
ostechnologies16
 
PPTX
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
dheeodoo
 
PPTX
Iobit Driver Booster Pro 12 Crack Free Download
chaudhryakashoo065
 
PDF
Humans vs AI Call Agents - Qcall.ai's Special Report
Udit Goenka
 
PPTX
Agentforce – TDX 2025 Hackathon Achievement
GetOnCRM Solutions
 
DOCX
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 
Foundations of Marketo Engage - Programs, Campaigns & Beyond - June 2025
BradBedford3
 
Azure AI Foundry: The AI app and agent factory
Maxim Salnikov
 
IObit Uninstaller Pro 14.3.1.8 Crack Free Download 2025
sdfger qwerty
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
Threat Modeling a Batch Job Framework - Teri Radichel - AWS re:Inforce 2025
2nd Sight Lab
 
arctitecture application system design os dsa
za241967
 
IDM Crack with Internet Download Manager 6.42 Build 41 [Latest 2025]
pcprocore
 
AI Software Development Process, Strategies and Challenges
Net-Craft.com
 
Automated Test Case Repair Using Language Models
Lionel Briand
 
IObit Driver Booster Pro 12.4-12.5 license keys 2025-2026
chaudhryakashoo065
 
For my supp to finally picking supp that work
necas19388
 
Code Once; Run Everywhere - A Beginner’s Journey with React Native
Hasitha Walpola
 
CodeCleaner: Mitigating Data Contamination for LLM Benchmarking
arabelatso
 
AWS Consulting Services: Empowering Digital Transformation with Nlineaxis
Nlineaxis IT Solutions Pvt Ltd
 
The Rise of Sustainable Mobile App Solutions by New York Development Firms
ostechnologies16
 
ERP Systems in the UAE: Driving Business Transformation with Smart Solutions
dheeodoo
 
Iobit Driver Booster Pro 12 Crack Free Download
chaudhryakashoo065
 
Humans vs AI Call Agents - Qcall.ai's Special Report
Udit Goenka
 
Agentforce – TDX 2025 Hackathon Achievement
GetOnCRM Solutions
 
Zoho Creator Solution for EI by Elsner Technologies.docx
Elsner Technologies Pvt. Ltd.
 

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