본문 바로가기

JavaScript

Node.js 심화 1주차_3

728x90

Node.js 심화 1주차_3

 

응집도 ↑ 결합도 ↓

 

/** OCP Before **/
function calculator(nums, option) {
  let result = 0;
  for (const num of nums) {
    if (option === "add") result += num; // option이 add일 경우 덧셈 연산을 합니다.
    else if (option === "sub") result -= num; // option이 sub일 경우 뺄셈 연산을 합니다.
    // 새로운 연산(기능)을 추가 하기 위해서는 함수 내부에서 코드 수정이 필요합니다.
  }
  return result;
}

console.log(calculator([2, 3, 5], "add")); // 10
console.log(calculator([5, 2, 1], "sub")); // -8

/** OCP After **/
function calculator(nums, callBackFunc) {
  // option을 CallbackFunc로 변경
  let result = 0;
  for (const num of nums) {
    result = callBackFunc(result, num); // option으로 분기하지 않고, Callback함수를 실행하도록 변경
  }
  return result;
}

const add = (a, b) => a + b; // 함수 변수를 정의합니다.
const sub = (a, b) => a - b;
const mul = (a, b) => a * b;
const div = (a, b) => a / b;
console.log(calculator([2, 3, 5], add)); // add 함수 변수를 Callback 함수로 전달합니다.
console.log(calculator([5, 2, 1], sub)); // sub 함수 변수를 Callback 함수로 전달합니다.

 


SOLID의 종류

  • 단일 책임의 원칙 (Single Responsibility Principle, SRP)
  • 개방-폐쇄 원칙 (Open-Closed Principle, OCP)
  • 리스코프 치환 원칙 (Liskov substitution principle, LSP)
  • 인터페이스 분리 원칙 (Interface segregation principle, ISP)
  • 의존성 역전 원칙 (Dependency Inversion Principle, DIP)

 

📌 설치(Terminal)

npm init -y
npm install -g typescript

tsc --init
tsc oop-for-ts.ts

node oop-for-ts.js

 

📄oop-for-ts.ts

/** Encapsulation **/
class User {
    private name: string;
    private age: number;
  
    setName(name: string) { // Private 속성을 가진 name 변수의 값을 변경합니다.
      this.name = name;
    }
    getName() { // Private 속성을 가진 name 변수의 값을 조회합니다.
      return this.name;
    }
    setAge(age: number) { // Private 속성을 가진 age 변수의 값을 변경합니다.
      this.age = age;
    }
    getAge() { // Private 속성을 가진 age 변수의 값을 조회합니다.
      return this.age;
    }
  }
  
  const user = new User(); // user 인스턴스 생성
  user.setName("이용우");
  user.setAge(28);
  console.log(user.getName()); // 이용우
  console.log(user.getAge()); // 28
//   console.log(user.name); // Error: User클래스의 name 변수는 private로 설정되어 있어 바로 접근할 수 없습니다.

 

📄oop-for-ts.js

/** Encapsulation **/
var User = /** @class */ (function () {
    function User() {
    }
    User.prototype.setName = function (name) {
        this.name = name;
    };
    User.prototype.getName = function () {
        return this.name;
    };
    User.prototype.setAge = function (age) {
        this.age = age;
    };
    User.prototype.getAge = function () {
        return this.age;
    };
    return User;
}());
var user = new User(); // user 인스턴스 생성
user.setName("이용우");
user.setAge(28);
console.log(user.getName()); // 이용우
console.log(user.getAge()); // 28
console.log(user.name); // Error: User클래스의 name 변수는 private로 설정되어 있어 바로 접근할 수 없습니다.

/** Inheritance **/
class Mother { // Mother 부모 클래스
    constructor(name, age, tech) { // 부모 클래스 생성자
      this.name = name;
      this.age = age;
      this.tech = tech;
    }
    getTech(){ return this.tech; } // 부모 클래스 getTech 메서드
  }
  
  class Child extends Mother{ // Mother 클래스를 상속받은 Child 자식 클래스
    constructor(name, age, tech) { // 자식 클래스 생성자
      super(name, age, tech);
    }
  }
  
  const child = new Child("이용우", "28", "Node.js");
  console.log(child.name); // 이용우
  console.log(child.age); // 28
  console.log(child.getTech()); // 부모 클래스의 getTech 메서드 호출: Node.js

 

캡슐
상속


 

쇼핑몰 프로젝트 코드 분리

 

📌 코드 분리하는 이유

  1. 가독성 향상(추상화, 코드을 이해하기 쉽도록 함수로 분리)
  2. 관리(유지보수) 용이

 

📄 원래코드

io.on('connection', (sock) => {
  console.log('새로운 소켓이 연결됐어요!');

  sock.on('BUY', (data) => {
    const emitData = {
      ...data,
      date: new Date().toISOString(),
    };

    io.emit('BUY_GOODS', emitData);
  });

... // 생략

  sock.on('disconnect', () => {
    console.log(sock.id, '연결이 끊어졌어요!');
  });
});

 

 

 

📄app.js

// 4. 소켓 연결 이벤트 핸들링
io.on('connection', (sock) => {
  const { watchBuying, watchByebye } = initSocket(sock);

  watchBuying();

  watchByebye();
});

function initSocket(sock) {
  console.log('새로운 소켓이 연결됐어요!');

  // 특정 이벤트가 전달됐는지 감지할 때 사용될 함수
  function watchEvent(event, func) {
    sock.on(event, func);
  }

  // 연결된 모든 클라이언트에 데이터를 보낼때 사용될 함수
  function sendMessageAll(event, data) {
    io.emit(event, data);
  }

  return {
    watchBuying: () => {
      watchEvent('BUY', (data) => {
        const emitData = {
          ...data,
          date: new Date().toISOString(),
        };
        sendMessageAll('BUY_GOODS', emitData);
      });
    },

    watchByebye: () => {
      watchEvent('disconnect', () => {
        console.log(sock.id, '연결이 끊어졌어요!');
      });
    },
  };
}

sendMessageAll 라는 함수를 호출하면

"지금 서버와 소켓으로 연결된 모든 클라이언트에 메세지를 보내는 기능"을 수행하는것만 알고 있으면 됨!

 


📄app.js

module.exports = http;

 

📄socket.js

const socketIo = require("socket.io"); // 1. 모듈 불러오기
const http = require("./app");
const io = socketIo(http); // 3. http 객체를 Socket.io 모듈에 넘겨서 소켓 핸들러 생성

// 4. 소켓 연결 이벤트 핸들링
io.on('connection', (sock) => {
    const { watchBuying, watchByebye } = initSocket(sock);
  
    watchBuying();
  
    watchByebye();
  });
  
  function initSocket(sock) {
    console.log('새로운 소켓이 연결됐어요!');
  
    // 특정 이벤트가 전달됐는지 감지할 때 사용될 함수
    function watchEvent(event, func) {
      sock.on(event, func);
    }
  
    // 연결된 모든 클라이언트에 데이터를 보낼때 사용될 함수
    function sendMessageAll(event, data) {
      io.emit(event, data);
    }
  
    return {
      watchBuying: () => {
        watchEvent('BUY', (data) => {
          const emitData = {
            ...data,
            date: new Date().toISOString(),
          };
          sendMessageAll('BUY_GOODS', emitData);
        });
      },
  
      watchByebye: () => {
        watchEvent('disconnect', () => {
          console.log(sock.id, '연결이 끊어졌어요!');
        });
      },
    };
  }

 

📄server.js

const http = require("./app");
require("./socket");

// 5. app 대신 http 객체로 서버 열기
http.listen(8080, () => {
    console.log("서버가 요청을 받을 준비가 됐어요");
  });

 

📌 test(Terminal)

node server

파일 분리 서버 실행

 

'JavaScript' 카테고리의 다른 글

Node.js 숙련주차 숙제 최종 제출  (0) 2022.12.28
Node.js 심화 1주차_4  (0) 2022.12.28
Node.js 심화 1주차_2  (0) 2022.12.26
Node 숙련 개인과제 ER다이어그램  (0) 2022.12.26
Node.js 심화 1주차_1  (0) 2022.12.26