✊ 필오의 개발일지
Back to Posts
2018년 8월 30일

CodeSpitz78 1/ 루틴과 결합도-응집도 모델

CodeSpitz78 1/ 루틴과 결합도-응집도 모델

🌕🌑🌑

🔥 코드스피츠 수업을 수강하면서 복습한 내용을 정리했습니다. 공부 후에는 풀어서 쉬운 언어로 설명할 수 있도록 연습하자.


1. Sub Routine

1-1. sub routine flow ### flow - 메모리에 적재되어있는 명령이 순차적으로 실행되는 과정을

의미한다. - sync라고도 한다.

routine

sub rotine

const routineA = b => { const result = b * 2; console.log(result); return result; }; const routineB = d => { const result = d * 3; console.log(result); return d; }; const b = 10, d = 30; const a = routineA(b); console.log(a); const c = routineB(d); console.log(c);

왜 함수라고 안하고 서브루틴 이라고 할까?

Arrow function

참고 : http://webframeworks.kr/tutorials/translate/arrow-function/ 

1-2. communicate with routine - main flow와 routine사이에 통신이라는 것을 한다. - 통신을 할 수

있는 매커니즘이 존재하는데, 이 매커니즘은 인자리턴이라고 알고 있다. - 자바스크립트에서는 return 없는 루틴은 없다.

자바스크립트는 LR 파서를 사용한다. - 자바스크립트로 작성된 파일을 파싱할 때 사용하는 방법 -

왼쪽에서 오른쪽, 위에서 아래로 파싱 - 할당은 RL 파서이다. - 수학적인 컨텍스트로 정의되어있다.

const routineA = arg => { const result = arg * 2; return result; }; const b = 10, c = 20, d = 30; const a = routineA(b) + routineA(c) + routineA(d);

덧셈 연산자에는 메모리가 필요하다.

1-3. sub routine in sub routine

- 루틴A에서 루틴B가 호출될때 루틴A에서는 keep이 이루어진다. 메모리를 기억하는 행위. 스냅샷으로 기억해둔다. - 루틴B가 진행되고 루틴A로 반환되면 keep은 사라진다.

코드로 표현하면

const routineA = arg => routineB(arg * 2); const routineB = arg => arg * 3; const b = 10; const a = routineA(b);

스택메모리, 콜스택

극단적인 예

- R6에 도달하기위해 5개의 메모리를 기억해야한다. - 콜스택, 함수의 스택메모리라고 부른다. - 자바에서는 메모리를 1000개까지 잡을 수 있도록 도와주고, 자바스크립트에서는 100번만 하라고.. - 브라우저마다 콜스택 지원이 다르다. - 스택이 너무 넘처서 죽는 상황 : stackoverflow

코드로 표현하면

const r1 = a => r2(a * 2); const r2 = a => r3(a * 2); const r3 = a => r4(a * 2); const r4 = a => r5(a * 2); const r5 = a => r6(a * 2); const r6 = a => a * 5; const b = 10; const a = r1(b);

서브루틴 안에 서브루틴이 들어가면 기본적으로 이런 일이 일어난다.

1-4. Value vs Reference 값과 참조 값은 메모리상에서 전달할 때마다 복사되는 형태, 참조는

메모리상에서 공유된 객체의 포인터만 전달되는 형식

POINT- 값이 넘어가면 복사된 값이 넘어가기 때문에 해당 루틴에서 값이 변화가 일어나도 main flow에서는 값에 영향을 주지 않는다. - 루틴에서 return 되는 값도 복사본이 넘어가기 때문에 main flow는 새로운 복사본을 받게 되는 개념이다. - 즉, main flow와 루틴 사이에는 의존성이 낮아진다. - 값의 정의는 언어마다 다르다. - 문자열은 자바스크립트에서 값이지만 자바에서는 참조로 정의되고 있다. - 자바스크립트는 6개(es6 기준: number, string, boolean, undefined, null, symbol)

상태안정이라고 부른다. State safe

const routine = a => a * 2; const flow1 = _ => { const b = 10, d = 20; const a = routine(b); const c = routine(c); return a + c; }; const flow2 = _ => { const b = 30, d = 40; const a = routine(b); const c = routine(c); return a + c; }; flow1(); flow2();

상황1: 참조로 넘겼을 때 참조값을 바꾸는 상황

const routine = ref => ['a', 'b'].reduce((p, c) => { // p는 콜백의 반환값, 초기값이 있을 경우 그값, 또는 콜백의 마지막 호출에서 이전에 반환된 누적값, // c는 배열 내 현재 처리되고 있는 요소. delete p[c]; return p; }, ref); const ref = { a: 3, b: 4, c: 5, d: 6 }; const a = routine(ref); ref === a; // true // 하나의 객체를 참조하고 있으므로.

상황2: 참조로 넘겼을 때 참조값을 readOnly로만

const routine = ({a, b, ...rest}) => rest; // spread 문법 // 새로운 객체가 반환된다. const ref = {a:3, b:4, c:5, d:6}; const a = routine(ref); ref !== a // true

spread 문법 (참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Spread_syntax )

상황3: 지역변수에 객체가 있거나, 리턴값이 객체인 경우

const routine = ref => { const local = ref; // 지역변수에 참조본을 담았다. local.e = 7; // ref 객체의 e에 7이 할당됨, 변화됨.. return local; }; const ref = { a: 3, b: 4, c: 5, d: 6 }; const a = routine(ref); ref === a; // true
const routine = ref => ({ ...ref, e: 7 }); const ref = { a: 3, b: 4, d: 5, d: 6 }; const a = routine(ref); ref !== a; // true

spread연산자는 순서에 영향이 있다. 이전에는 hash map이였는데, linked hash map이됨. 객체를 넣는 순서가 보장이 된다.


2. Structured design ## 높은 응집도, 낮은 결합도 High Cohesion, Loose Coupling

Larry constantine_ Structured design - 어떤 함수 내부의 코드가 높은 응집도를 갖는다? - 하나의 함수로 여러가지 처리를 할 수 있다. - 결합도가 높다? - 의존성이 높다.

좋은 서브루틴이란 높은 응집도와 낮은 결합도를 갖도록 짜야한다!

2-1. 결합도 coupling 👎👌👍

Content (👎 초강결합)

A클래스 속성v가 변경되면 즉시 B클래스가 깨짐

const A = class { constructor(v) { this.v = v; } }; const B = class { constructor(a) { this.v = a.v; } }; const b = new B(new A(3));

Common (👎 초강결합)

Common클래스 변경 시 즉시 A,B클래스가 깨짐

const Common = class { constructor(v) { this.v = v; } }; const A = class { constructor(c) { this.v = c.v; } }; const B = class { constructor(c) { this.v = c.v; } }; const a = new A(new Common(3)); const b = new B(new Common(5));

External (👎 초강결합)

A, B 클래스는 외부의 정의에 의존함. member의 json 구조가 변경되면 깨짐.

const A = class { constructor(member) { this.v = member.name; } }; const B = class { constructor(member) { this.v = member.age; } }; fetch('/memger') .then(res => res.json()) .then(member => { const a = new A(member); const b = new B(member); });

Control (👎 초강결합)

A클래스 내부의 변화는 B 클래스의 오작동을 유발

const A = class { process(flag, v) { switch (flag) { case 1: return this.run1(v); case 2: return this.run2(v); case 3: return this.run3(v); } } }; const B = class { constructor(a) { this.a = a; } noop() { this.a.process(1); } echo(data) { this.a.process(2, data); } }; const b = new B(new A()); b.noop(); b.echo('test');

Stamp (👎👌 유사약결합)

const A = class { add(data) { data.count++; } // data 전체를 받을 필요가 없고 count만 받았어야 한다. // 넓은 범위로 받게 됨. // count라는 변수명이 바뀌면 다 바뀌어야한다. }; const B = class { constructor(counter) { this.counter = counter; this.data = { a: 1, count: 0 }; } count() { // 필요한 값만 내려주자. this.counter.add(this.data); } }; const b = new B(new A()); b.count(); b.count();

Data (👌 약결합)

const A = class { add(count) { return count + 1; } }; const B = class { constructor(counter) { this.counter = counter; this.data = { a: 1, count: 0 }; } count() { this.data.count = this.counter.add(this.data.count); } }; const b = new B(new A()); b.count(); b.count();

2-2. 응집도 cohesion 👎👌👍 ### Coincidental 우연히 👎 - 우연히 모여 있는.. - 아무런 관계가 없음.

const Util = class { static isConnect() {} static log() {} static isLogin() {} };

Logical 👌

const Math = class { static sin(r) {} static cos(r) {} static random() {} static sqrt(v) {} };

Temporal 시간의 순서 👌

const App = class { init() { this.db.init(); this.net.init(); this.asset.init(); this.ui.start(); } };

Procedural 👌

const Account = class { login() { p = this.ptoken(); // permanet token s = this.stoken(p); // session token if (!s) this.newLogin(); else this.auth(s); } };

Communicational 👌

const Array = class { push(v) {} pop() {} shift() {} unshift(v) {} };

Sequential

const Account = class { ptoken() { return this.pk || (this.pk = IO.cookie.get('ptoken')); } stoken() { if (this.sk) return this.sk; if (this.pk) { const sk = Net.getSessionFromPtoken(this.pk); sk.then(v => this.sk); } } auth() { if (this.isLogin) return; Net.auth(this.sk).then(v => this.isLogin); } };

Functional 👍

결합도와 응집도의 조화

높은 응집성을 갖게 되면 높은 커플링은 갖게된다. 결합도와 응집도의 조화를 목표로 로직을 짜야한다.

PreviousCodeSpitz78 2/ 루틴 심화
Next4/ 함수와 프로토타입 체이닝 (2)

Related

© 2025 Felix