소프트웨어를 설계할 때 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용할 할 수있는 훌륭한 해결책이다➡️ 코드를 작성할 때 어떤 방법으로 작성하면 좋을지에 대한 문제해결의 방법론이라고 볼수있다"이미 잘 만들어져있는 것을 처음부터 만들 필요가 없다!"
비슷하거나 동일한 양식 또는 유형들이 반복되어 나타난다는 의미이며, 문제와 해결책도 동일한 유형이나 양식을 통해 쉽게 찾을 수 있다.패턴은 공통언어를 만들어주며 사용되는 요소 사이의 의사 소통을 원활하게 해주는 역할을 한다.
구현 방법이나 언어에 의존적이지 않으며 다양한 상황에 적용할 수 있는 일종의 템플릿과 같다(한 패턴에 변형을 가하거나 어떠한 요구사항을 반영하면 다른 패턴으로 변형되는 특징이 있다)콘테스트 ➡️ 문제 ➡️ 해결
🖐❗️ 앞으로 계속 언급하게 될 클래스(class)와 객체(object) 알고가기클래스 = 객체를 찍어내기 위한 틀, '빵틀' (설계도)객체 = 클래스에서 찍혀나온 결과물, '빵' (결과물)클래스로 객체 즉, 메모리를 찍어 낸것이다.

각각의 패턴이 어떤 일을 하기 위한 것인지에 관한 것
객체 생성에 관련된 패턴화
- 유연성은 높게, 코드유지는 쉽게, 인스턴스화를 통해 추상화 하는 방법이다
- 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공한다
객체 결합 (구조)에 관련된 패턴화
- 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴이다
- 예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다
객체 간 커뮤니케이션 패턴화
- 객체나 클래스 사이의 알고리즘이나 책임 분배에 관련된 패턴
- 한 객체가 혼자 수행할 수 없는 작업을 여러 개의 객체로 어떻게 분배하는지,또 그렇게 하면서도 객체 사이의 결합도를 최소화하는 것에 중점을 둔다.
싱글턴(Singleton) 패턴
class의 객체가 해당프로세스에 하나만 만들어지고 그것을 반복해서 사용함

var singleton = (function() {
// 비공개 프로퍼티 정의
var instance;
// 비공개 메서드 정의
function init() {
// singleton 인스턴스 정의
return {
// 공개 프로퍼티 정의
prop: 'value',
// 공개 메서드 정의
method: function() {
return 'hello'
}
};
}
// 공개 메서드인 getInstance를 정의한 객체, 비공개 프로퍼티 및 메서드에 접근 가능(클로저)
return {
getInstance: function() {
// 인스턴스가 선언이 안되있는경우 인스턴스 생성
if (!instance) {
instance = init();
}
// 인스턴스가 선언이 되있는 경우 인스턴스 반환
return instance;
}
}
})()
var singleton1 = singleton.getInstance();
console.log(singleton1.method());
var singleton2 = singleton.getInstance();
console.log(singleton1 === singleton2); // true
자바스크립트 ES6 문법 ver.
let instance = null;
class Singleton{
constructor(){
if(instance) return instance;
this.name = "heecheolman";
this.age = 24;
instance = this;
}
}
var firstSingleton = new Singleton();
var secondSingleton = new Singleton();
console.log(firstSingleton === secondSingleton); // true
console.log(instance === firstSingleton); // true
팩토리 메서드(Factory Method) 패턴
객체 생성 처리를 서브 클래스로 분리해 처리하도록 캡슐화하는 패턴

템플릿 메서드 패턴이란?
상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서는 추상 메서드를 통해 구체적인 내용을 결정하도록 하는 디자인 패턴이다
상위클래스 = 중요한 뼈대결정 / 추상 메소드의 구현은 하위클래스에게 맡김
⬆️
하위클래스 = 상위클래스에서 상속받은 추상메소드의 구체적인 내용을 결정 class CafeLatte {
constructor() {
this.price = 3000;
}
getPrice() {
return this.price;
}
}
class CaramelLatte {
constructor() {
this.price = 5000;
}
getPrice() {
return this.price;
}
}
class LatteFactory() {
// 구체화하는 로직을 묶어 응집도는 높이고, 코드는 깔끔하게
static create(latteType) {
if(latteType === 'cafe') {
return new CafeLatte();
} else if(latteType === 'caramel') {
return new CaramelLatte();
}
}
}
let latte = LatteFactory.create('caramel');
latte.getPrice(); // 5000
커피종류 추가하기
function coffeeFactory(type) {
let coffee;
if(type === 'latte') coffee = new Latte();
else if(type === 'espresso') coffee = new Espresso();
else if(type === 'cappuccino') coffee = new Cappuccino();
else if(type === 'mocha') coffee = new Mocha();
return coffee;
}
추상 팩토리(Abstract Factory Method)패턴
'객체 집합' 생성 용이구체적인 클래스에 의존하지 않고 서로 관련성이 있거나 독립적인 여러 객체의 집합을 생성하기 위한 인터페이스를 제공한다

function takeOutCoffee(type) {
let coffee;
if(type === 'latte') coffee = new Latte();
else if(type === 'espresso') coffee = new Espresso();
else if(type === 'cappuccino') coffee = new Cappuccino();
else if(type === 'mocha') coffee = new Mocha(); // 새로운 커피가 추가되어 추가한 if 문
coffee.prepare();
coffee.make();
coffee.boxing();
return coffee;
}
takeOutCoffee()는 coffee type을 받아서 해당하는 커피를 가공한 후, 완성된 coffee를 리턴해주는 함수이다
효율적인 코드를 위해 로직 속 공통된 부분끼리 묶는다.type에 따라 해당하는 인스턴스를 생성하였다
function takeOutCoffee(type) {
let coffee = coffeeFactory(type);
coffee.prepare();
coffee.make();
coffee.boxing();
return coffee;
}
// 커피 타입을 넘겨주면, 인스턴스를 만들어주는 공장!
function coffeeFactory(type) {
let coffee;
if(type === 'latte') coffee = new Latte();
else if(type === 'espresso') coffee = new Espresso();
else if(type === 'cappuccino') coffee = new Cappuccino();
else if(type === 'mocha') coffee = new Mocha();
return coffee;
}
이렇게 구현하면 새로운 커피가 아무리 추가되어도 takeOutCoffee 함수를 고칠 필요는 없다.
하지만 많은양의 커피가 추가 된다고 가정할 때, 한없이 if문을 추가하기는 비효율적이다
그렇다면 만든다는 행위만 외부에 정의해 두고 사용할 값만 계속 추가한다면!..
class CoffeeFactory {
static createCoffee(factory) { //coffeeFactory를 factory로 추상화함
return factory.createCoffee(); // 인스턴스를 만드는 행위를 추상화 시킴
}
}
class LatteFactory {
static createCoffee () {
return new Latte();
}
}
class EspressoFactory {
static createCoffee () {
return new Espresso();
}
}
class CappuccinoFactory {
static createCoffee () {
return new Cappuccino();
}
}
// 실행
CoffeeFactory.createCoffee(LatteFactory);
CoffeeFactory.createCoffee(EspressoFactory);
CoffeeFactory.createCoffee(CappuccinoFactory);
행위에 대한 구현은 세부적인 팩토리들을 만들어서 createCoffee()라는 공통적인 메서드를 이용하여 생성하도록 했다.추상 팩토리는 인스턴스의 생성을 서브클래스에게 위임함으로써 의존성을 낮춘다.
function takeOutCoffee(factory) { //추상화 시킨 factory를 인자로 넣어줌
let coffee = coffeeFactory.createCoffee(factory);
coffee.prepare();
coffee.make();
coffee.boxing();
return coffee;
}
스크립트 (구체적인 클래스를 지정하지 않고 인터페이스를 통해 서로 연관되는 객체들을 그룹으로 표현함)
빌더(Builder) 패턴
복잡한 객체(인스턴스)를 단계별로 조립하는 패턴

프로토타입(Prototype) 패턴
원본 객체를 복사함으로써 객체를 생성함
