함수와 OOP(1) - Routine & Structured Design

임쿠쿠·2021년 8월 1일
0

OOP

목록 보기
1/3
post-thumbnail

함수를 단순히 입력값과 산출값으로 보는게 아닌 Flow로 바라보기

Routine Flow

const routineA = b => {
	const result = b * 2;
  	console.log(result);
  	return result;
};

const routineB = d => {
	const result = d * 3;
  	console.log(result);
  	return d;
};

// (1)
const b = 10, d = 30;
// Main Flow에서 서브루틴에게 값을 전달 시 인자를 사용하고 값을 return을 통해 받아옴
const a = routineA(b);
const c = routineB(d);


// (2)
// 연산이 들어가면 메모리가 만들어지고 연산이 될때까지 메모리가 해제 되지 않는다.
const m = routineA(b) + routineA(d)

key feature

  • 연산이 들어가면 메모리가 만들어지고 연산이 될때까지 메모리가 해제 되지 않는다.

Sub Routine In Routine

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

// routine안에 routine이 있으면 routineB를 불러 올때까지 routineA를 keep 해야함.
const b = 10;
const a = routineA(b);

key feature

  • 루틴안에 루틴이 연달아 이어질때 메모리를 계속 기억해야하며 CALL STACK, 함수의 스택 메모리라고 표현한다.
  • Stack overflow ~ 스택이 너무 쌓여 오류 발생

VALUE VS REFERENCE

// 값을 전달 시
const routine = arg => arg * 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;
};
// 값을 전달하고 값을 받으면 STATE SAFE 함수이다.
flow1();
flow2();

// ref 전달 시 ref === a 된다.
const routineRef = ref => ['a', 'b'].reduce((p, c) => {
  delete p[c];
  return p;
}, ref)
const ref = {a:3, b:4}
const a = routine(ref);

// ref 읽기 전용으로 사용시 ref !== a
const routine = ({a,b,...rest}) => rest
const ref = {a:3, b:4, c:5, d:6};
const a = routine(ref);

key feature

  • 값은 메모리 상에서 전달될때 마다 복사
  • 참조는 공유된 포인터만 전달
  • 루틴에게 값을 전달 시 복사되어 전달되므로 둘 사이의 의존성이 낮아진다.
  • 참조를 전달 시 routine안에서 읽기전용으로만 사용한다. ~ 함수의 사이드 이펙트 효과 없앰

Structured design

Coupling(결합도)

// content 결합도(강결합) ~ 쓰지말것
const A = class {
  constructor(v) {
    this.v = v;
  }
};

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

key feature

  • Content / Common 결합 : class A가 변경되면 B도 영향 ~ 강결합
// External 결합도(강결합)
// member는 외부 api json으로 받았다고 가정
const member = { name: "jisub", age: 30 };

const A = class {
  constructor(member) {
    this.v = member.name;
  }
};

const B = class {
  constructor(member) {
    this.v = member.age;
  }
};

const a = new A(member);
const b = new B(member);

key feature

  • External 결합 : 외부에서 주어진 객체(fetch api)에 의해 class A,B를 쓸수 밖에 없는 경우가 있다. -> Swagger로 관리(관리의 대상)
// STAMP - 강결합 & 유사약결합
const A = class {
  add(data) {
    data.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());

key feature

  • STAMP 결합 : 기능이 분리 됐지만, 문제점은 data.count가 아닌 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();

key feature

  • DATA 결합 : 필요한 count값만 전달 ~ count를 cnt로 바꿔도 괜찮다. 다만 아직까지 data에 의존적임

Cohesion(응집도)

// COINCIDENTAL ~ 대충 비슷한 것 끼리 모아둠
const Util = class{
  static isConnect(){}
  static log(){}
  static isLogin(){}
}
// LOGICAL
// Logical의 문제점은 해당 로직을 알고있어야 한다는 전제가 깔림
const Math = class{
  static sin(r){}
  static cos(r){}
  static random(){}
  static sqrt(v){}
}
// TEMPORAL
// 시간에 대한 의존성은 flow가 언제든지 바뀔수 있어서 위험하다.
const Initialize = class{
  init(){
    this.db.init();
    this.net.init();
    this.assert.init();
    this.ui.start();
  }
}
// PROCEDURAL
// 절차에 대한 의존성 ~ 토큰 확인 후 새로운 로그인 OR 권한 확인
const Account = class{
  login(){
    p = this.ptoken();
    s = this.stoken();
    if(!s) this.newLogin();
    else this.auth(s);
  }
}
// COMMUNICATIONAL
// 권한과 책임이 생김으로써 '역할'이 생김 ~ 기능들을 응집
const Array = class{
  push(v){}
  pop(){}
  shift(){}
  unshift(){}
  }
}

// SEQUENTIAL
// PROCEDURAL + COMMUNICATIONAL

// FUNCTIONAL
// 역할모델에 충실하게 단일한 기능이 의존성 없이 생성된 경우

결론

  • 높은 응집성 낮은 결합도는 모순된 관계이다.
  • 응집성 높아 질수록 결합도도 높아진다. ~ 두개의 이상적인 목표를 달성하기란 어렵다.
  • 프로그래밍의 정수는 이 둘의 밸런스를 맞추고 적절한 선을 찾는 것이다.
profile
Pay it forward

0개의 댓글