-
함수 1코-드 스피츠/함수와 oop 2019. 1. 3. 17:24
-이 게시글은 계속 수정함을 목표로 하는 거십니다
1. 서브루틴이 어케 작동하나
2. 루틴이 통신할 때 인자와 결과값을 어떻게 주고 받나
3. 서브루틴 안에 서브루틴이 호출되었을 때의 문제들
4. 함수를 잘 짜기 위해서 결합도와 응집도 모델을 어떻게 이용해야 하는지
https://www.youtube.com/watch?v=YsMhHGG-9Ow&index=1&list=PLBNdLLaRx_rKOFzA3txlG5rf9ZaVUuvmv
1. [sub routine flow]
[13:59]
flow: 메모리에 적재되어 있는 명령이 순차적으로 ??에 의해서 실행되는 과정. 이 과정에는 무엇도 개입할 수 없고 한 번 적재된 메모리의 명령들은 쭈욱 한번에 실행이 됩니다. 니놈들이 아는 용어로 sync라고 부릅니다. 동기화 명령들이 flow를 이룹니다.
[14:26]
routine: 루틴은 flow 그 자체를 의미 합니다. 메모리에 적재한 명령어 세트가 바로 루틴입니다. 그러나 이것을 한 번만 실행하는 게 아니라 여러 번 실행할 수 있는 방법이 갖춰져 있으면 routine이라고 부릅니다.
[14:49]
main routine: 메인 루틴은 서브루틴과 상대되는 개념. 절대적인 개념이 아닙니다.. 부른 쪽이 메인루틴, 점프에서 다른 루틴으로 실행되면 서브루틴.
메인flow로 쭉 가다가 서브루틴을 만나면 그 동네에 갔다가 다시 돌아오는 행위가 일어 납니다.
서브루틴은 갔다가 돌아오는 포인트가 있습니다.
[21:59]
루틴의 개념이 flow의 통제를 다른쪽에 줬다 뺏는다는 것이 중요합니다.
[22:05]
니놈들에게 함수는 return값이 있는 수학적인 개념에만 사로잡혔을 가능성이 있습니다.
[22:24]
그런데 우리가 이 관점에서 보는 건 수학적인 의미의 함수가 아닌, flow control에 있어서 어떤 일이 일어나는지 집중하는 겁니다. flow, 메모리의 명령들이 어떤식으로 흘러가는지에 집중합니다. 이 관점에서의 함수를 routine이라고 하는거다 이썌끼야
기계적 관점의 함수(routine) => 수학적 관점의 함수(function)의 순으로 공부하는 것이 니놈 건강에 좃습니다
갑작스런 es6 설명 [23:40]
es6에서 function이라는 키워드가 나오면 걍 잘못됐다고 생각하세요.
이유-> this가 순수한 함수에서 필요한가? this는 언제 필요한가? -> 메소드에서. es6의 메소드는 클래스에서 메소드 문법으로 정리하게 되어 있음.
즉-> es6에서 function 키워드를 쓰는 경우는 X.
즉-> 함수는 죄다 애로우펑션, 메소드는 죄다 클래스 메소드.
그럼 왜 있음-> 하위호완성 보장.
2. [COMMUNICTAE WITH ROUTINE]
[25:44]
메인 플로우와 루틴간에는 흐름 뿐만 아니라 값을 주고 받는 메커니즘이 있습니다.
이 메커니즘은 주로 인자와 return 입니다.
갑작스런 JS 설명 [26:54]
참고로 자스는 리턴없는 루틴이 없습니다. return이 없는 루틴에는 return undefined가 됩니다. 자스에서 undefined는 두가지 입니다. 진짜 없는 undefined와 undefined값을 갖는 undefined가 있습니다.
없는 undefined: new Array(10)의 원소값.
있는 undefined: a = undefined
진짜 없는 undefined로 empty 고려중. 근데 chrome 개발자 도구에서는 현재 empty로 뜨긴 한다.
다른 언어에서는 return값이 있는 루틴과 없는 루틴으로 나뉘는 경우가 대부분.
[29:13]
LR파서: 자바스크립트로 너님들이 작성한 텍스트 파일을 파싱할 때 사용하는 방법
예외: 변수 할당. 따라서 존나 많은 버그가 여기서 일어납니다.
갑작스런 개발자의 덕목 [31:31]
덕목1: 공리가 없으니 다 설명 가능해야 합니다.
덕목2: 観察力
3. [SUB ROUTINE IN SUB ROUTINE]
[35:36]
keep: 루틴에서 다른 서브루틴을 부르면 현재 루틴을 메모리에서 기억합니다.
[36:28]
keep은 존내 중요한데 루틴을 두개 반복하면 하나는 keep해두지 않으면 두번째 루틴으로 갈 수가 없습니다.
[39:10] 이거시 콜스텍, 함수의 스텍 메모리
4. [VALUE VS REFERENCE]
값과 참조
[43:00]
값은 메모리상에서 전달할 때마다(할당할때마다) 복사되는 형태 입니다.
참조는 메모리상에서 공유된 객체를 가리키는 포인터(주소)만 전달되는 형식 입니다.
참조로 전달된 값을 바꾸면, 원래 값도 바뀝니다 => 잘못된 표현 입니다. 값은 하나이기 때문에 두 놈 다 같은 값 수정 하고 있을 뿐입니다.
[43:33]
서브루틴과 메인루틴간 통신할 때 넘겨주고 받는 값이 참조냐 값이냐에 따라서 다른 양상을 만들어 냅니다.
값으로 주고 받았을 경우
[44:11]
서로 복사한 값만 주고 받기 때문에 메인 루틴과 서브 루틴간의 의존성이 굉장히 낮아집니다. 원래 있던 값을 건드릴 수 없습니다.
[44:29]
value는 언어에서 정합니다. 보통 값으로 보는 type을 primitive data type으로 봅니다. 그외에는 모두 reference 입니다.
[45:48]
그렇기 때문에 함수는 참조값입니다. 복사되지 않습니다.
따라서 이렇게 value만으로 통신하면 state safe 상태안전이라고 부르는 상태가 됩니다.
정리 [48:28]
메인플로우가 서브루틴에게 주는 인자와 서브루틴이 메인플로우에게 주는 return이 둘 다 value인 경우는 크게 신경 쓰지 않아도 안정적인 함수입니다.. 완전수학적함수라고도 합니다. 어디에서 누가 몇번이나 불러도 신경 안써도 됩니다. 따라서 함수를 짤 때 가장 먼저 고려해야할 대상입니다.
참조로 주고받을 경우
[52:25]
참조로 주고 받을 때는 Read only로 쓰세요. 권장사항입니다.
갑작스런 es8[53:00]
es6에서는 해체 구문, es8에선 객체rest구문 지원합니다.
객체rest구문은 정해져 있는 key를 해체하고 남은 애들을 묶어서 객체로 만드는 문법입니다.
{a, b, ...rest}로 a, b가 빠진 새로운 객체가 태어납니다.
const routine = ({a, b, ...rest}) => rest;
객체를 읽기전용으로 사용하고 새로운 객체를 복사해서 return 했습니다.
따라서 rest는 {c:5, d:6}의 새로운 객체가 되어서 ref와 다른 객체가 되었습니다.
정리 [54:20]
첫번째, 가능한 루틴의 인자로 참조를 넘기지 않습니다.
불가피하다면 참조로 넘어온 인자를 read only로 사용하세요.
그러면 함수의 side effect를 줄일 수 있습니다.
[55:36]
리턴으로 참조를 줘야 할 경우.
새로운 참조값으로 return 합니다.
지역변수를 만들 때도 새로운 참조값, return할 때도.
갑작스런 es6 [56:14]
es6부터 객체 리터럴의 변화가 생겼습니다.
선언한 순서대로 객체의 순서가 정해집니다.
내부적으로는 그전까지는 해쉬맵, 지금은 링크드 해쉬맵입니다.
레알 정리[57:14]
인자로 들어오는 참조값은 read only
지역변수나 return은 새 객체로 return, best of best는 value로 return하세욜
[57:30]
비용문제 -> 새 객체로 return해서 걱정되시나요? 너님같은 쪼렙은 걱정 ㄴㄴ
존나 레알 전체적으로 다시 정리[58:15]
루틴에 객체를 주고받을 때 인자인 경우엔 리드온리로 사용한다, 로컬변수나 리턴값에서는 새 객체를 반환하도록 노력하자!\(^0^)/
크게 중요한 개념 두가지[59:00]
핵쉼 개념 - 높은 응집도, 낮은 결합도.
좋은 프로그램, 좋은 함수, 좋은 서브루틴은 높은 응집도와 낮은 결합도를 갖게 짜야한다.
어떤 함수 내부의 코드 , 혹은 함수의 묶음이 높은 응집도를 갖는다는 것은 내가 어떤 일을 처리할 때 여기저기에 있는 걸 끌어오지 않고 걔만 가져오면 다 처리할 수 있다는 개념이다. 나는 배열을 가져오면 배열안에 있는 메소드(push, pop등)을 이용해서 배열에 관련된 조작을 한꺼번에 할 수 있다. 그러케 생각하시자나여? 다른 언어같은 경우에는 배열을 다룰때 다른 함수군을 가지고 배열을 다룰 때도 있다. 이러면 응집도가 낮은 것이다.
결합도라는 것은 이 함수를 쓰려면 앞에 적어도 마흔개의 함수가 준비되어 있어야함, 이런 것. 이런 예는 결합도가 매우 높은 것.
그러니 바람직한 방향은 응집도는 높은데 결합도는 낮추는 것이다. 사용자는 이 함수를 쓰고 싶을 때 언제라도 막 쓸 수 있다. 예를 들어 Math 메소드가 있다. 아무때나 쓸 수 있다. 의존성이 거의 제로에 가깝다. 또 우리가 Math 패키지를 보면 우리는 일반적인 수학 문제를 해결할 수 있는 메소드가 제공될 것이라고 생각한다. 그것이 바로 응집도가 높은 것이다.
예를 들어 사인 함수는 사인 패키지에서, 코사인은 Math 패키지에서 가져와야 한다면 응집도가 떨어진다. 우리가 사인 함수를 쓰려면 라디안 변환표를 처리하는 라디안 함수를 import해야한다면 결합도가 올라가는 것이다.
이 목적을 달성하기 위해 이러한 형태들을 공부할 필요가 있다.
[01:01:52]
복잡하고 나쁜 쪽이 위, 좋고 바람직한 것이 아래쪽.
Coupling[01:02:33]
짝지우기. 상대가 없으면 뒤짐. 결합도와 의존성dependency은 다르다. 결합도는 좀 더 넓은 범위를 포괄한다. 의존성은 방향이 있기 때문에 커플링과는 조금 다른 개념이다. 커플링은 둘이 의존을 양쪽에서 하고 있는 것을 말한다.
Content coupling
가장 나쁜 커플링.
빨간 박스는 쓰지 마시오.
강결합 중의 하나.
어떤 모듈 두개가 커플링할 때
[1:04:24]
이것이 왜 나쁜가
클래스 A의 내용이 조금이라도 바뀌면 클래스 B는 무조건 망가지니까.
컨텐츠 결합은 의존하는 대상의 내장을 까서 다 알고 있는 경우다.
Common Coupling
이때 common은 (인메모리안에 존재하고 있는) 전역객체 또는 공유객체로 생각하면 된다.
클래스 A, B를 만들 때 모두 common을 참조하고 있다.
content coupling보다 조금 나은 것. common객체를 잘 관리하는 것으로 클래스의 여파들을 계산할 수 있다. 하지만 1:1 커플링이 common 커플링으로 바뀌었을 뿐이다.
니들이 지금까지 짠 건 여기까지임(쑻)
[01:07:19]