본문 바로가기
TIL

팩토리 패턴

by 은지:) 2024. 2. 5.
728x90
반응형

 

 

팩토리 패턴

 

const car1 = {
    name: "차1",
    price: "1000만원",
    getInfo: () => this.name+"의 가격은 "+this.price+" 입니다."
}
const car2 = {
    name: "차2",
    price: "2000만원",
    getInfo: () => this.name+"의 가격은 "+this.price+" 입니다."
}

 

이렇게 생기는 객체들

반복 짱 많음

 

 

이걸 만드는 걸 함수화해서 공장을 만드는 거임

const factory = (param) => {
    return {
        name: param.name,
        price: param.price,
        getInfo: ()=> this.name+"의 가격은 "+this.price+" 입니다."
        }
    }
    
const result1 = factory({name: "차1", price: "1000만원"});
const result2 = factory({name: "차2", price: "2000만원"});

 

 

근데 여기서 문제는 getInfo가 중복됨

중복 메서드가 만들어짐

 

이걸 프로토 타입을 사용해서 줄일 수 있음

 

 

function Factory2(param) {
    this.name = param.name;
    this.price = param.price;
}

Factory2.prototype.getInfo = function() {
    console.log("이거 프로토타입", this.name + this.price);
}

const obj1 = new Factory2({ name: "Example1", price: 100 });
const obj2 = new Factory2({ name: "Example2", price: 200 });

obj1.getInfo(); // 출력: 이거 프로토타입 Example1100
obj2.getInfo(); // 출력: 이거 프로토타입 Example2200

 

 

 

 

-------------

예쁘게 화살표 함수 써보려다가

화살표 함수에는 this, prototype 쓸 수 없다는 걸 찾음

화살표 함수가 선언적이고 함수에 변수를 넣어서 쓰는 형태이기 때문에

호이스팅에 있어서 안전할 지라도

 

생성자 관련해서는 그냥 function(){} 형태 쓰는 게 좋은 거 같음

---------------

 

 

프로토 타입

 

 

자바스크립트 프로토타입

=> 자바스크립트의 모든 객체들은 부모 역할을 하는 객체와 연결 되어 있음(최상위는 object임)

이런 부모 역할을 하는 객체들을 js에서는 prototype이라고 함

 

$(function(){
    const Student = function(name, korean, english, math){
        this.name = name;
        this.korean = korean;
        this.english = english;
        this.math = math;
        this.average = function(){
            return (this.korean+this.english + this.math)/3;
        }
    }
    console.dir(Student);
});

 

요런 애들이 있을 때

ƒ Student(name, korean, english, math)
  english: undefined
  korean: undefined
  math: undefined
  name: undefined
  arguments: (...)
  caller: (...)
  length: 4
  name: "Student"
  prototype: {constructor: ƒ}
  __proto__: ƒ ()
  [[FunctionLocation]]: VM61:1
  [[Scopes]]: Scopes[1]
    0: Closure (...)

 

대충 이렇게 찍힘

저기 prototype은 생성자 함수 객체임

=> 객체를 생성할 때 프로토 타입을 상속받음

 

$(function(){
    const Student = function(name, korean, english, math){
        this.name = name;
        this.korean = korean;
        this.english = english;
        this.math = math;
    }
    Student.prototype.average = function(){
        return (this.korean + this.english + this.math)/3
    }
});

 

아예 프로토 타입에 넣어버림

부모에게 넣어서 상속 받아서 쓰는 개념인 거임

 

이렇게 되면 Student 생성자 함수로 생성된 객체들은 average 라는 프로토 타입을 가지고 있어서

사용할 수 있음

function Student(name, korean, english, math){
    this.name = name;
    this.korean = korean;
    this.english = english;
    this.math = math;
}

// 프로토타입에 average 메서드 추가
Student.prototype.average = function(){
    return (this.korean + this.english + this.math) / 3;
}

// DOMContentLoaded 이벤트 리스너 등록
document.addEventListener('DOMContentLoaded', function() {
    // 페이지 로드가 완료된 이후에 실행
    // 이제 Student 생성자 함수와 average 메서드를 사용할 수 있음
    const student1 = new Student('John', 90, 85, 92);
    console.log(student1.average());  // 예상 출력: 89
});

 

요렇게 사용 가능

 

 

---------

프로토 타입 깊게

---------

 

C++은 프로토타입 기반 언어가 아니라 클래스 기반 언어입니다. 프로토타입 기반 언어는 JavaScript와 같이 객체를 생성하기 위한 프로토타입이라는 객체를 사용하여 상속을 구현하는 언어를 의미합니다. 이런 언어에서는 클래스가 없고, 객체는 다른 객체로부터 직접 생성되며, 상속은 프로토타입 체인을 통해 이루어집니다. 반면에 C++은 클래스와 객체 지향 프로그래밍을 지원하는 언어로, 클래스를 사용하여 객체를 정의하고 이를 통해 인스턴스를 생성합니다. C++은 클래스를 통한 상속을 지원하며, 클래스 간의 계층 구조를 통해 코드를 구성하고 재사용할 수 있도록 합니다.

 

 


 

그럼 이걸 class형으로 만든다면?

 

class Car{
    constructor(info){
        this.name = info.name;
        this.price = info.price;
    }
    getInfo(){
        return this.name+"의 가격은 "+this.price+" 입니다.";
    }
    static factory(name){
        if(name === "Avante"){
           return new Avante();
        }else if(name === "Sonata"){
           return new Sonata();
        }
    }
}
class Sonata extends Car{
    constructor(){
        super({name: "쏘나타", price: "2,386 ~ 3,367만원"});
    }
}
class Avante extends Car{
    constructor(){
        super({name: "아반테", price: "1,570 ~ 2,453만원"});
    }
}
const avante = Car.factory("Avante");
const sonata = Car.factory("Sonata");
console.log(avante, sonata);

 

 

 

 

-----------

자바스크립트 static

-----------

 

class App {
  static init() {   
    console.log("static init called");
  }
}

const appInstance = new App();
//appInstance.init()을 실행했을 때, init()은 정적 메서드이고,
//appInstance는 APP의 인스턴스이기 때문에 error가 발생합니다. 

// error Uncaught TypeError: appInstance.init is not a function
console.log(appInstance.init()); 
 
//클래스에서 호출할 때 init() 메서드가 실행됩니다. 
App.init();

 

static 을 붙이면 클래스에서 호출해야 됨

인스턴스를 만들지 않고 사용할 수 있다는 장점

 

-----------

자바스크립트 super

-----------

class 부모클래스 {
  constructor(x) {
    this.x = x;
  }
}

class 자식클래스 extends 부모클래스 {
  constructor(x, y) {
    super(x); // 부모 클래스의 생성자 호출
    this.y = y;
  }
}

const 객체 = new 자식클래스(1, 2);
console.log(객체.x); // 1
console.log(객체.y); // 2

 

부모생성자 쓰는 super

 

 

====================================

 

 

그리고 이걸 함수형으로 만들어봤음

 

const CAR_INFO = {
  "Sonata": { name: "쏘나타", price: "2,386 ~ 3,367만원" },
  "Avante": { name: "아반테", price: "1,570 ~ 2,453만원" }
};


// 생성자
const createCar = (name) => ({
  name: CAR_INFO[name].name,
  price: CAR_INFO[name].price,
  getInfo: function() {
    return this.name + "의 가격은 " + this.price + " 입니다.";
  }
})

const carFactory = (name) => createCar(name);

const avante = carFactory("Avante");
const sonata = carFactory("Sonata");


console.log(avante.getInfo())
console.log(sonata.getInfo())

 

 

 

 

 

출처: https://aljjabaegi.tistory.com/617 [알짜배기 프로그래머:티스토리]

728x90
반응형

댓글