8000 capsulable/README-KR.md at master Β· hmmhmmhm/capsulable Β· GitHub
[go: up one dir, main page]

Skip to content

Latest commit

Β 

History

History
315 lines (238 loc) Β· 11.8 KB

README-KR.md

File metadata and controls

315 lines (238 loc) Β· 11.8 KB

Capsulable

Build Status

순수 μžλ°”μŠ€ν¬λ¦½νŠΈ 클래슀 μΊ‘μŠν™” κ΅¬ν˜„ λͺ¨λ“ˆ

icon

μΊ‘μŠλŸ¬λΈ” λͺ¨λ“ˆμ€ μžλ°”μŠ€ν¬λ¦½νŠΈ ν΄λž˜μŠ€μ—μ„œ μ‰½κ²Œ μ ‘κ·Όμ œν•œμž κ°œλ…μ„ μ‚¬μš©ν•  수 있게 λ•μŠ΅λ‹ˆλ‹€. ν΄λ‘œμ € κ°œλ…μ„ 톡해 μΊ‘μŠν™” 및 은닉화 κ°œλ…μ„ κ΅¬ν˜„ν•©λ‹ˆλ‹€.

μ„€μΉ˜λ°©λ²•

npm i capsulable --save

μ™œ 이 λͺ¨λ“ˆμ΄ ν•„μš”ν•œκ°€μš”?

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κΈ°λ³Έ λ³€μˆ˜κ°œλ…μ—λŠ” _ 와 __으둜 ν‘œν˜„ν•˜λŠ” prvate 및 protected λ³€μˆ˜ κ°œλ…μ΄ μ‘΄μž¬ν•˜μ§€λ§Œ, 타 ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή λ³€μˆ˜λ₯Ό μ½λŠ” 것을 λ§‰μ§€λŠ” λͺ»ν•©λ‹ˆλ‹€. λ˜ν•œ protected κ°œλ…μ˜ 경우 상속 이후 μ ‘κ·Όμ œν•œμ˜ κ°œλ…μ΄ μ•„μ§κΉŒμ§€ λͺ¨ν˜Έν•©λ‹ˆλ‹€. λ‚΄λΆ€ λ³€μˆ˜μ˜ 은닉성이 ν•„μš”ν•œ ν΄λž˜μŠ€μ—λŠ” 클래슀 λ³€μˆ˜μ— 보닀 λͺ…ν™•ν•œ μ ‘κ·Όμ œν•œμž κ°œλ…μ΄ ν•„μš”ν•©λ‹ˆλ‹€.

κ·Έλƒ₯ Closure λ‚˜ Symbol 으둜 맀번 λ§Œλ“€λ©΄ λ˜μ§€ μ•Šλ‚˜μš”?

λ¬Όλ‘  κ·Έλ ‡κ²Œ 해도 상관은 μ—†μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 클래슀 μΈμŠ€ν„΄μŠ€ λ§ˆλ‹€ 각기 λ‹€λ₯Έ Private λ³€μˆ˜ 곡간을 λ§Œλ“€κ³  μ‹Άκ±°λ‚˜(μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†λŠ”), 상속 이후에도 각기 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ λ‹€λ₯Έ Protected λ³€μˆ˜ 곡간을 λ§Œλ“€κ³  μ‹Άκ±°λ‚˜, νŠΉμ • νŒ¨ν‚€μ§€ μ‚¬μ΄μ—μ„œλ§Œ μ ‘κ·Όκ°€λŠ₯ν•œ Protected Static λ³€μˆ˜κ³΅κ°„μ„ 맀번 직접 λ§Œλ“ λ‹€λ©΄ λ‹€μ†Œ 힘이 λΉ μ§€λŠ” μž‘μ—…μΌ 수 μžˆμŠ΅λ‹ˆλ‹€. Capsulable 은 μ•ˆμ „ν•œ 은닉성과 ν™•μž₯μ„±, 그리고 상속 클래슀 및 νŒ¨ν‚€μ§€ κ°„μ˜ Protected 및 Protected Static λ³€μˆ˜ κ°œλ…μ„ μ œκ³΅ν•©λ‹ˆλ‹€.


μΊ‘μŠν™” 된 클래슀 μ •μ˜λ°©λ²•

Capsulable 은 class 의 constructor ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ 데이터 ν•„λ“œλ₯Ό κ³΅μœ ν•©λ‹ˆλ‹€. (μ΄λŠ” 즉 Capsulable 이 μ΅œμ’…μ μœΌλ‘œ 항상 μžμ‹ 클래슀둜 ꡬ성 됨을 μ˜λ―Έν•©λ‹ˆλ‹€.) μΊ‘μŠν™” ν•˜κΈΈ μ›ν•˜λŠ” ν΄λž˜μŠ€λŠ” 사전에 Capsulable 을 ν†΅ν•΄μ„œ constructor μ—μ„œ 데이터 ν•„λ“œλ₯Ό 상속 λ°›μ•„μ•Όν•©λ‹ˆλ‹€. μ˜ˆμ‹œ 상 문법은 ES5둜 ν‘œκΈ°λ˜λ‚˜, Babel을 ν†΅ν•œ ES6 λ¬Έλ²•μœΌλ‘œ κ΅¬ν˜„ν•΄λ„ λ©λ‹ˆλ‹€.

클래슀 μ •μ˜ 예제

// A.js
const Capsulable = require('capsulable')
const Field = Capsulable()

class A {
    constructor(_field){
        // 데이터 ν•„λ“œλ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.
        Field(this, _field)

        // μ•„λž˜μ™€ 같은 μ½”λ“œλ₯Ό ν†΅ν•΄μ„œ
        // 클래슀 λ‚΄ ν•¨μˆ˜ μž‘μ„± μ‹œ
        // 데이터 ν•„λ“œμ— μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.
        Field(this).private
        Field(this).protected
        Field(this).protectedStatic
    }
}

module.exports = A

클래슀 μΊ‘μŠν™” 예제

// index.js
const Capsulable = require('./capsulable')
const A = require('./A')

// Capsulable에 클래슀 μ›ν˜•μ„ λ„£μœΌλ©΄
// μΊ‘μŠν™” 된 ν΄λž˜μŠ€κ°€ λ°˜ν™˜λ©λ‹ˆλ‹€.
const SharedA = Capsulable(A)

// μΊ‘μŠν™” 된 클래슀λ₯Ό ν†΅ν•΄μ„œ
// μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
let sharedA = new SharedA()

Field λ³€μˆ˜ 접근법

Field(this).private
Field(this).protected
Field(this).protectedStatic

Capsulable λͺ¨λ“ˆμ€ 각 ν΄λž˜μŠ€λ§ˆλ‹€ 데이터 ν•„λ“œλΌλŠ” 것을 μƒμ„±ν•˜λŠ”λ°, 이 데이터 ν•„λ“œμ—λŠ” private, protected, protectedStatic λ³€μˆ˜ν˜•νƒœ(getter)둜 μ œκ³΅λ©λ‹ˆλ‹€. 데이터 ν•„λ“œλŠ” 클래슀의 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ μƒμ„±λ˜λ―€λ‘œ 데이터 ν•„λ“œ μ ‘κ·Όμ‹œμ—λŠ” μΈμŠ€ν„΄μŠ€κ°€ ν•„λ“œμ— 인자둜 μ£Όμ–΄μ Έμ•Ό ν•©λ‹ˆλ‹€.

Private ν•„λ“œ μ‚¬μš©λ²•

Field(this).private.set(key, value) // => Boolean
Field(this).private.exist(key)  // => Boolean
Field(this).private.get(key) // => Object
Field(this).private.getAll() // => Object
Field(this).private.remove(key) // => Boolean
Field(this).private.removeAll() // => Boolean

Private ν•„λ“œλŠ” 각 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ 격리된 곡간을 κ°€μ§€λ©° 타 μΈμŠ€ν„΄μŠ€κ°€ μ ‘κ·Όν•  수 없도둝 μ°¨λ‹¨λ©λ‹ˆλ‹€. κ°œλ°œμžκ°€ 같은 클래슀 λ‚΄μ—μ„œ Field(this) λ₯Ό λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€μ—κ²Œ λ…ΈμΆœμ‹œν‚¬ 수 μžˆλŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜μ§€λ§Œ μ•ŠλŠ”λ‹€λ©΄ λ³€μˆ˜μ˜ 은닉성은 μœ μ§€λ  κ²ƒμž…λ‹ˆλ‹€.

Protected ν•„λ“œ μ‚¬μš©λ²•

Field(this).protected.set(className, key, value) // => Boolean
Field(this).protected.exist(className, key)  // => Boolean
Field(this).protected.get(className, key) // => Object
Field(this).protected.getAll(className) // => Object
Field(this).protected.remove(className, key) // => Boolean
Field(this).protected.removeAll(className) // => Boolean

Protected ν•„λ“œλŠ” 각 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ 격리된 곡간을 κ°€μ§€λ©°, μ ‘κ·Όν•˜κ³ μž ν•˜λŠ” className 을 ν•¨μˆ˜ μ‚¬μš©μ‹œ 맨 처음 인자둜 μ œκ³΅ν•΄μ•Όν•©λ‹ˆλ‹€. Protected ν•„λ“œλŠ” 클래슀 상속이 λ°œμƒν–ˆμ„λ•Œ λΆ€λͺ¨ ν΄λž˜μŠ€μ™€ μžμ‹ 클래슀 μ‚¬μ΄μ—λ§Œ(λ˜ν•œ 같은 νŒ¨ν‚€μ§€) κ³΅μœ λ˜μ–΄μ•Ό ν•˜λŠ” 데이터 μš΄μš©μ— μ ν•©ν•©λ‹ˆλ‹€.

Protected Static ν•„λ“œ μ‚¬μš©λ²•

Field(this).protectedStatic.set(className, key, value) // => Boolean
Field(this).protectedStatic.exist(className, key)  // => Boolean
Field(this).protectedStatic.get(className, key) // => Object
Field(this).protectedStatic.getAll(className) // => Object
Field(this).protectedStatic.remove(className, key) // => Boolean
Field(this).protectedStatic.removeAll(className) // => Boolean

Protected Static ν•„λ“œλŠ” 각 μΈμŠ€ν„΄μŠ€μ™€ 곡유된 곡간을 κ°€μ§€λ©°, μ ‘κ·Όν•˜κ³ μž ν•˜λŠ” className을 ν•¨μˆ˜ μ‚¬μš©μ‹œ 맨 처음 인자둜 μ œκ³΅ν•΄μ•Όν•©λ‹ˆλ‹€. Protected Static ν•„λ“œλŠ” λΆ€λͺ¨ν΄λž˜μŠ€μ™€ μžμ‹ν΄λž˜μŠ€κ°€ 같은 데이터λ₯Ό μš΄μš©ν•˜λ©΄μ„œ λ™μ‹œμ— λͺ¨λ“  클래슀 μΈμŠ€ν„΄μŠ€λ“€μ΄ 같은 데이터λ₯Ό κ³΅μœ ν•΄μ•Ό ν•˜λŠ” 데이터 μš΄μš©μ— μ ν•©ν•©λ‹ˆλ‹€.


μΊ‘μŠν™” 된 νŒŒμƒ 클래슀 μ •μ˜λ°©λ²•

νŒŒμƒ 클래슀λ₯Ό μƒμ„±ν–ˆμ„ λ•Œ λΆ€λͺ¨ν΄λž˜μŠ€μ™€ μžμ‹ν΄λž˜μŠ€κ°€ Protected 와 ProtectedStatic ν˜•νƒœμ˜ 데이터 ν•„λ“œλ₯Ό κ³΅μœ ν•˜κ²Œ ν•˜λ €λ©΄ μ•„λž˜μ™€ 같은 방법을 톡해 κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (상속을 진행해도 Private 데이터 ν•„λ“œλŠ” κ³΅μœ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.)

νŒŒμƒν΄λž˜μŠ€ μ •μ˜

// B.js
const Capsulable = require('capsulable')
const A = require('./A')
const Field = Capsulable()

class B extends A {
    constructor(_field){
        // νŒŒμƒ ν΄λž˜μŠ€λŠ” constructor λ₯Ό ν†΅ν•΄μ„œ
        // 받은 ν•„λ“œ 객체λ₯Ό super ν‚€μ›Œλ“œλ₯Ό ν†΅ν•΄μ„œ
        // λ°˜λ“œμ‹œ λΆ€λͺ¨ 클래슀둜 λ„˜κ²¨μ•Όν•©λ‹ˆλ‹€.
        super(_field)

        // 데이터 ν•„λ“œλ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.
        Field(this, _field)
    }
}

module.exports = B

νŒŒμƒν΄λž˜μŠ€ μΊ‘μŠν™”

// index.js
const Capsulable = require('./capsulable')
const B = require('./B')

// Capsulable에 클래
9695
슀 μ›ν˜•μ„ λ„£μœΌλ©΄
// μΊ‘μŠν™” 된 ν΄λž˜μŠ€κ°€ λ°˜ν™˜λ©λ‹ˆλ‹€.
const SharedB = Capsulable(B)

// μΊ‘μŠν™” 된 클래슀λ₯Ό ν†΅ν•΄μ„œ
// μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
let sharedB = new SharedB()

이미 μΊ‘μŠν™” 된 클래슀의 νŒŒμƒλ°©λ²•

이미 원 클래슀λ₯Ό Capsulable 둜 μΊ‘μŠν™” μ‹œν‚¨ 이후에 λ‹€μ‹œν•œλ²ˆ λ‹€λ₯Έ ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή 클래슀λ₯Ό νŒŒμƒλ°›κ³  싢은 경우, μ•„λž˜μ™€ 같은 방법을 톡해 이λ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

// C.js
const Capsulable = require('./capsulable')
const B = require('./B')
const SharedB = Capsulable(B)
const Field = Capsulable()

class C extends SharedB{
    constructor(inherit){
        // λΆ€λͺ¨ 클래슀인 Capsulable μ—μ„œ
        // 데이터 ν•„λ“œλ₯Ό μ—­μœΌλ‘œ λ°›μ•„μ˜΅λ‹ˆλ‹€.
        let hook = {}
        super(hook)

        // 데이터 ν•„λ“œλ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.
        Field(this, hook.field)

        // 이후 λ‹€μ‹œν•œλ²ˆ νŒŒμƒμ΄ κ°€λŠ₯ν•˜λ„λ‘,
        // νŒŒμƒλμ„ μ‹œ 객체λ₯Ό λ³΅μ‚¬ν•΄μ€λ‹ˆλ‹€.
        if(inherit) Capsulable(hook, inherit)
    }
}

module.exports = C

// index.js
const Capsulable = require('./capsulable')
const C = require('./C')

// Capsulable에 클래슀 μ›ν˜•μ„ λ„£μœΌλ©΄
// μΊ‘μŠν™” 된 ν΄λž˜μŠ€κ°€ λ°˜ν™˜λ©λ‹ˆλ‹€.
const SharedC = Capsulable(C)

// μΊ‘μŠν™” 된 클래슀λ₯Ό ν†΅ν•΄μ„œ
// μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
let sharedC = new SharedC()

νŒ¨ν‚€μ§€ 곡간 생성방법

Capsulable μ—λŠ” Java 의 Package κ°œλ…μ΄ λ―Έμ•½ν•˜κ²Œ κ΅¬ν˜„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜μ²˜λŸΌ μ—¬λŸ¬ 클래슀λ₯Ό ν•œλ²ˆμ— μΊ‘μŠν™” ν•  경우, ν•΄λ‹Ή ν΄λž˜μŠ€λ“€μ˜ μΈμŠ€ν„΄μŠ€λ“€μ€ Protected 데이터 ν•„λ“œμ™€ Protected Static 데이터 ν•„λ“œκ°€ μžλ™μœΌλ‘œ κ³΅μœ λ©λ‹ˆλ‹€.

주의: ν•˜λ‚˜μ˜ νŒ¨ν‚€μ§€μ— λ“±λ‘λ˜λŠ” μ—¬λŸ¬ 클래슀 μ›ν˜•λ“€μ€ μ„œλ‘œ 이름이 κ²ΉμΉ  수 μ—†μŠ΅λ‹ˆλ‹€.

// index.js
const A = require('./A')
const B = require('./B')
const C = require('./C')

// Capsulable 에 인자둜
// 배열에 클래슀 μ›ν˜•λ“€μ„ λ‹΄μ•„ μ „λ‹¬ν•˜λ©΄
// 이λ₯Ό ν•˜λ‚˜μ˜ νŒ¨ν‚€μ§€λ‘œ κ΅¬μ„±ν•©λ‹ˆλ‹€.
let packages = Capsulable([A, B, C])

// μ•„λž˜μ™€ 같이 packages.* λ₯Ό 톡해
// μΊ‘μŠν™” 된 클래슀 μ›ν˜•μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
let packA = new packages.A()
let packB = new packages.B()
let packC = new packages.C()

νŒ¨ν‚€μ§€ 생성 이후 클래슀 λ‘œλ“œ

// index.js
const A = require('./A')
const B = require('./B')
const C = require('./C')
const D = require('./A')

// Capsulable 에 인자둜
// 배열에 클래슀 μ›ν˜•λ“€μ„ λ‹΄μ•„ μ „λ‹¬ν•˜λ©΄
// 이λ₯Ό ν•˜λ‚˜μ˜ νŒ¨ν‚€μ§€λ‘œ κ΅¬μ„±ν•©λ‹ˆλ‹€.
let packages = Capsulable([A, B, C])

// packages._load ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ
// μ›ν•˜λŠ” 클래슀 μ›ν˜•μ„ νŒ¨ν‚€μ§€ 곡간 ꡬ성
// 이후에도 ν•΄λ‹Ή νŒ¨ν‚€μ§€μ— μΆ”κ°€μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
packages._load(D)

// packages.* λ₯Ό ν†΅ν•΄μ„œ
// μΆ”κ°€λœ 클래슀 μ›ν˜•μ— μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.
let packD = new packages.D()

νŒ¨ν‚€μ§€ 생성 이후 클래슀 μ–Έλ‘œλ“œ

packages._load(D)
let packD = new packages.D()

// packages._unload ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ
// νŒ¨ν‚€μ§€μ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” 클래슀 μ›ν˜•μ„
// ν•΄λ‹Ή νŒ¨ν‚€μ§€μ—μ„œ μ‚­μ œμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
packages._unload(D)

// 이미 νŒ¨ν‚€μ§€μ— μΆ”κ°€λœ 클래슀 μ›ν˜•μœΌλ‘œ
// 클래슀 μΈμŠ€ν„΄μŠ€κ°€ κ΅¬μ„±λœ 경우
// ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€μ—λŠ” 영ν–₯이 μ—†μŠ΅λ‹ˆλ‹€.

Final Class κ΅¬ν˜„

클래슀 μ›ν˜•μ˜ μΊ‘μŠν™” 이후 νŒŒμƒ 클래슀λ₯Ό 더 이상 λ§Œλ“€κΈΈ μ›μΉ˜ μ•ŠλŠ” 경우 Capsulable ν•¨μˆ˜ μ‚¬μš©μ‹œ 2번째 인자둜 final λͺ¨λ“œλ₯Ό μ μš©μ‹œν‚΄μœΌλ‘œμ¨ νŒŒμƒ ν΄λž˜μŠ€μ™€ 데이터 ν•„λ“œλ₯Ό κ³΅μœ ν•˜μ§€ μ•Šλ„λ‘ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (클래슀의 νŒŒμƒμ„ μ™„μ „νžˆ λ§‰μ§€λŠ” λͺ»ν•˜λ‚˜, 데이터 ν•„λ“œκ°€ κ³΅μœ λ˜λŠ” 것을 막을 μˆ˜λŠ” μžˆμŠ΅λ‹ˆλ‹€.)

// index.js
const Capsulable = require('./capsulable')
const A = require('./A')

// 2번째 인자둜 final을 적으면
// νŒŒμƒν΄λž˜μŠ€μ™€ 데이터 ν•„λ“œλ₯Ό κ³΅μœ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
const SharedA = Capsulable(A, 'final')

// μΊ‘μŠν™” 된 클래슀λ₯Ό ν†΅ν•΄μ„œ
// μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
let sharedA = new SharedA()

μž‘μ—… λͺ©λ‘

  • Private λ³€μˆ˜ κ΅¬ν˜„
  • Protected λ³€μˆ˜ κ΅¬ν˜„
  • Protected Static λ³€μˆ˜ κ΅¬ν˜„
  • 각 λ³€μˆ˜μ˜ 단계별 μ΄ˆκΈ°ν™” κ³Όμ • κ΅¬ν˜„
  • 톡합 데이터 ν•„λ“œ κ΅¬ν˜„
  • μƒμ†κΈ°λ°˜μ˜ μœ μΆœμ—†λŠ” 데이터 ν•„λ“œ 곡유 κ΅¬ν˜„
  • νŒ¨ν‚€μ§€κ°„ Protected 데이터 곡유 κ΅¬ν˜„
  • Helper λ₯Ό ν†΅ν•œ Private λ³€μˆ˜ μΈμžλ‹¨μΆ• κ΅¬ν˜„
  • μΊ‘μŠν™” 이후 상속 클래슀 μΆ”κ°€ 및 재 μΊ‘μŠν™” κ΅¬ν˜„
  • ν…ŒμŠ€νŠΈ μœ λ‹› κ΅¬ν˜„
  • assert κ°€λ³€λͺ¨λ“ˆν™” ν•˜μ—¬ 쒅속성 μ™„μ „ 배제 κ΅¬ν˜„
  • final 클래슀 κ΅¬ν˜„
  • final λ³€μˆ˜ κ΅¬ν˜„
  • μΊ‘μŠν™” 된 클래슀의 constructor κ°€λ³€λ³€μˆ˜ 인자 κ΅¬ν˜„
  • μΊ‘μŠν™” 된 클래슀의 constructor κ°€λ³€λ³€μˆ˜μ˜ νŒŒμƒν΄λž˜μŠ€ 곡유 κ΅¬ν˜„

LICENSE

MIT

0