코드 만들기: JavaScript 디자인 패턴

WBOY
풀어 주다: 2024-08-24 19:32:46
원래의
184명이 탐색했습니다.

Cook Up Your Code: JavaScript Design Patterns

이것을 상상해 보세요: 여러분은 맛있는 식사를 요리하기 위해 부엌에 서 있습니다. 모든 재료가 준비되어 있지만 따라야 할 레시피가 없습니다. 실험을 시작하지만 곧 압도감을 느끼게 됩니다. 한 접시에 소금을 너무 많이 넣으면 다른 접시가 태워집니다. 명확한 계획이 없으면 요리는 추측으로 엉망이 됩니다.

소프트웨어를 만드는 것은 이런 느낌일 수 있습니다. 모든 도구와 노하우를 갖추고 있지만 잘 조직된 접근 방식이 없으면 새로운 기능을 추가하는 것이 답답한 퍼즐이 될 수 있습니다. 코드에서 수행해야 하는 작업이 무엇인지 이해하고 있지만 모든 것이 함께 작동하도록 하는 최선의 방법을 찾고 있습니까? 여기서 상황이 복잡해집니다. 작은 오류 하나가 버그와 얽힌 코드로 가득 찬 구멍 속으로 굴러떨어지는 자신을 발견하게 됩니다.

디자인 패턴을 입력하세요. 수년에 걸쳐 코더가 전수해 온 오랜 시간 테스트를 거친 레시피입니다. 이러한 재사용 가능한 수정 사항은 땀을 흘리지 않고도 소프트웨어 제작의 까다로운 부분을 처리하는 데 도움이 됩니다. 디자인 패턴이 정확히 무엇인지, 디자인 패턴이 코딩 생활을 어떻게 더 쉽게 만들어 주는지, 그리고 디자인 패턴이 강력하고 유지 관리하기 쉬운 앱을 구축하는 데 중요한 이유에 대해 알아봅니다. 더 흥미롭게 만들기 위해 설명 전반에 걸쳐 요리 용어를 사용할 예정입니다. 솔직히 말해서 좋은 요리 쇼를 좋아하지 않는 사람이 어디 있겠습니까?

그럼 디자인 패턴이란 무엇일까요? 더 나은 앱을 구축하는 데 어떻게 도움이 될까요?

디자인 패턴은 소프트웨어 디자인에서 반복되는 문제와 테마에 적용할 수 있는 재사용 가능한 솔루션 템플릿입니다. 이는 소프트웨어 설계의 일반적인 문제를 해결하기 위해 노력하는 숙련된 개발자가 시도하고 테스트한 솔루션을 담은 훌륭한 요리책이 될 것입니다. 가이드라인에 따르면 디자인 패턴을 사용하면 앱에서 유지 관리 및 재사용이 가능한 코드를 얻을 수 있습니다.

디자인 패턴은 본질적으로 해결하는 문제에 따라 창의적 디자인 패턴, 구조적 디자인 패턴, 행동 디자인 패턴의 세 가지 범주로 분류됩니다.

디자인 패턴은 해결하는 문제에 따라 세 가지 범주로 나뉩니다. 창조적인 디자인 패턴, 구조적인 디자인 패턴, 행동적인 디자인 패턴이 있습니다.

창의적인 디자인 패턴: 재료 및 준비

창의적 디자인 패턴은 객체 생성을 위한 메커니즘을 제공합니다. 쿠킹쇼의 맥락에서 이러한 패턴은 요리하기 전에 재료를 모으고 준비하는 것과 같습니다. 이 범주에 속하는 일부 패턴에는 생성자, 팩토리, 추상, 프로토타입, 싱글톤 및 빌더가 있습니다. 더 잘 이해하려면 아래 세 가지 예를 살펴보세요.

1. 싱글톤

몇 세대에 걸쳐 특별한 냄비에서만 만들 수 있는 가족만의 비법 소스가 있다고 상상해 보세요. 물론 냄비가 다르면 소스의 맛이 같을 수는 없습니다. 이것이 바로 싱글톤이 하는 일입니다. 클래스가 단일 인스턴스로 제한되는 디자인 패턴입니다.

으아악

2. 팩토리 메소드

팩토리 메소드는 객체 생성을 위한 일반 인터페이스를 제공하므로 원하는 객체 종류를 지정할 수 있습니다. 우리 요리쇼에서는 레시피북이 바로 공장이에요. 만들고 싶은 요리의 종류에 따라 필요한 레시피(물체)가 제공됩니다.

으아악

팩토리 메소드는 복잡한 객체 생성 시나리오에서 유용합니다. 예를 들어 환경에 따라 다른 인스턴스를 생성하거나 유사한 객체를 많이 관리하는 경우입니다.

*3. 추상 공장 *

객체의 일반적인 사용법에서 구현 세부 사항을 캡슐화합니다. 이를 설명하는 가장 좋은 방법은 식사 키트 배달 서비스를 고려하는 것입니다. 이탈리아 요리, 중국 요리, 멕시코 요리 등 무엇을 요리하든 이 서비스는 모든 것이 완벽하게 들어맞도록 손에 쥔 요리에 맞춰 재료와 조리법을 포함한 모든 것을 배달해 드립니다.

으아악

구조적 디자인 패턴: 요리 기술 및 도구

구조적 디자인 패턴은 객체 구성에 중점을 두고 다양한 객체 간의 관계를 설정하는 간단한 방법을 식별합니다. 이는 시스템의 한 부분이 변경될 때 전체 구조가 안정적으로 유지되도록 도와줍니다. 요리에서 이러한 패턴은 재료를 조화롭고 맛있는 요리로 결합하는 데 사용하는 기술과 도구를 나타냅니다.

이 카테고리에 속하는 패턴에는 Decorator, Facade, Flyweight, Adapter 및 Proxy가 포함됩니다.

1. 외관 패턴

Facade 패턴은 더 복잡한 코드 본문에 편리한 고급 인터페이스를 제공하여 기본 복잡성을 효과적으로 숨깁니다. 수석 셰프의 복잡한 작업을 단순화하는 부주방장을 상상해 보십시오. 수석 셰프가 요리의 마지막 손질에 집중할 수 있도록 수셰프가 재료를 모아 준비하고 모든 것을 정리합니다

// Complex Subsystem class IngredientPrep { chop(ingredient) { console.log(`Chopping ${ingredient}.`); } measure(amount, ingredient) { console.log(`Measuring ${amount} of ${ingredient}.`); } } class CookingProcess { boil(waterAmount) { console.log(`Boiling ${waterAmount} of water.`); } bake(temp, duration) { console.log(`Baking at ${temp} degrees for ${duration} minutes.`); } } class Plating { arrangeDish(dish) { console.log(`Arranging the ${dish} on the plate.`); } garnish(garnish) { console.log(`Adding ${garnish} as garnish.`); } } // Facade Class class SousChef { constructor() { this.ingredientPrep = new IngredientPrep(); this.cookingProcess = new CookingProcess(); this.plating = new Plating(); } prepareDish(dishName) { console.log(`Starting to prepare ${dishName}...`); this.ingredientPrep.chop('vegetables'); this.ingredientPrep.measure('2 cups', 'flour'); this.cookingProcess.boil('1 liter'); this.cookingProcess.bake(180, 30); this.plating.arrangeDish(dishName); this.plating.garnish('parsley'); console.log(`${dishName} is ready!`); } } // Client Code const sousChef = new SousChef(); sousChef.prepareDish('Lasagna'); // Output: // Starting to prepare Lasagna... // Chopping vegetables. // Measuring 2 cups of flour. // Boiling 1 liter of water. // Baking at 180 degrees for 30 minutes. // Arranging the Lasagna on the plate. // Adding parsley as garnish. // Lasagna is ready!
로그인 후 복사

2. Decorator

The Decorator pattern is used to modify existing systems by adding features to objects without significantly altering the underlying code. If our applications require many distinct types of objects, this pattern is ideal. For instance, when making coffee, we start with a basic cup and then dynamically add ingredients like milk, sugar, or whipped cream. The Decorator pattern lets us add the base coffee without changing the core recipe.

// Base Component class Coffee { constructor() { this.description = 'Basic Coffee'; } getDescription() { return this.description; } cost() { return 2; // Base cost for a simple coffee } } // Decorator Class class CoffeeDecorator { constructor(coffee) { this.coffee = coffee; } getDescription() { return this.coffee.getDescription(); } cost() { return this.coffee.cost(); } } // Concrete Decorators class Milk extends CoffeeDecorator { constructor(coffee) { super(coffee); } getDescription() { return `${this.coffee.getDescription()}, Milk`; } cost() { return this.coffee.cost() + 0.5; } } class Sugar extends CoffeeDecorator { constructor(coffee) { super(coffee); } getDescription() { return `${this.coffee.getDescription()}, Sugar`; } cost() { return this.coffee.cost() + 0.2; } } class WhippedCream extends CoffeeDecorator { constructor(coffee) { super(coffee); } getDescription() { return `${this.coffee.getDescription()}, Whipped Cream`; } cost() { return this.coffee.cost() + 0.7; } } // Client Code let myCoffee = new Coffee(); console.log(`${myCoffee.getDescription()} costs $${myCoffee.cost()}`); // Basic Coffee costs $2 myCoffee = new Milk(myCoffee); console.log(`${myCoffee.getDescription()} costs $${myCoffee.cost()}`); // Basic Coffee, Milk costs $2.5 myCoffee = new Sugar(myCoffee); console.log(`${myCoffee.getDescription()} costs $${myCoffee.cost()}`); // Basic Coffee, Milk, Sugar costs $2.7 myCoffee = new WhippedCream(myCoffee); console.log(`${myCoffee.getDescription()} costs $${myCoffee.cost()}`); // Basic Coffee, Milk, Sugar, Whipped Cream costs $3.4
로그인 후 복사

3. Flyweight

The Flyweight pattern is a classical structural solution for optimizing code that is repetitive, slow, and inefficiently shares data. It aims to minimize memory in use in an application by sharing as much data as possible with related objects. Think of common ingredients like salt, pepper, and olive oil that are used in many dishes. Instead of having separate instances of these ingredients for each dish, they are shared across dishes to save resources. For example, you put salt on fried chicken and beef stew from the same jar.

// Flyweight Class class Ingredient { constructor(name) { this.name = name; } use() { console.log(`Using ${this.name}.`); } } // Flyweight Factory class IngredientFactory { constructor() { this.ingredients = {}; } getIngredient(name) { if (!this.ingredients[name]) { this.ingredients[name] = new Ingredient(name); } return this.ingredients[name]; } getTotalIngredientsMade() { return Object.keys(this.ingredients).length; } } // Client Code const ingredientFactory = new IngredientFactory(); const salt1 = ingredientFactory.getIngredient('Salt'); const salt2 = ingredientFactory.getIngredient('Salt'); const pepper = ingredientFactory.getIngredient('Pepper'); salt1.use(); // Using Salt. salt2.use(); // Using Salt. pepper.use(); // Using Pepper. console.log(ingredientFactory.getTotalIngredientsMade()); // 2, Salt and Pepper were created only once console.log(salt1 === salt2); // true, Salt is reused
로그인 후 복사

Behavioral Design Patterns: The Cooking Process and Interaction

Behavioral patterns focus on improving or streamlining the communication between disparate objects in a system. They identify common communication patterns among objects and provide solutions that distribute the communication responsibility among different objects, thereby increasing communication flexibility. In a cooking show, behavioral design patterns are the way we cook the dish, the process of cooking, and how various parts of the kitchen interact with each other to create the final dish. Some of the behavioral patterns are Iterator, Mediator, Observer, and Visitor.

1.Observer

The Observer pattern is used to notify components of state changes. When a subject needs to inform observers about a change, it broadcasts a notification. If an observer no longer wishes to receive updates, they can be removed from the list of observers. For example, once the head chef finishes preparing a dish, all the assistant chefs need to be notified to begin their tasks, such as plating or garnishing. The Observer pattern allows multiple chefs (observers) to be notified when the head chef (subject) completes a dish.

// Subject Class class HeadChef { constructor() { this.chefs = []; this.dishReady = false; } addObserver(chef) { this.chefs.push(chef); } removeObserver(chef) { this.chefs = this.chefs.filter(c => c !== chef); } notifyObservers() { if (this.dishReady) { this.chefs.forEach(chef => chef.update(this.dishName)); } } prepareDish(dishName) { this.dishName = dishName; console.log(`HeadChef: Preparing ${dishName}...`); this.dishReady = true; this.notifyObservers(); } } // Observer Class class Chef { constructor(name) { this.name = name; } update(dishName) { console.log(`${this.name}: Received notification - ${dishName} is ready!`); } } // Client Code const headChef = new HeadChef(); const chef1 = new Chef('Chef A'); const chef2 = new Chef('Chef B'); headChef.addObserver(chef1); headChef.addObserver(chef2); headChef.prepareDish('Beef Wellington'); // Output: // HeadChef: Preparing Beef Wellington... // Chef A: Received notification - Beef Wellington is ready! // Chef B: Received notification - Beef Wellington is ready!
로그인 후 복사

2. Mediator

The Mediator pattern allows one object to be in charge of the communication between several other objects when an event occurs. While it does sound similar to the Observer pattern, the key difference is that the Mediator handles communication between objects rather than just broadcasting changes. For example, let's think of our kitchen with its grill, bakery, and garnish station sections. A kitchen coordinator (mediator) handles the communication so that all the preparations are done on time.

// Mediator Class class KitchenCoordinator { notify(sender, event) { if (event === 'dishPrepared') { console.log(`Coordinator: Notifying all stations that ${sender.dishName} is ready.`); } else if (event === 'orderReceived') { console.log(`Coordinator: Received order for ${sender.dishName}, notifying preparation stations.`); } } } // Colleague Classes class GrillStation { constructor(coordinator) { this.coordinator = coordinator; } prepareDish(dishName) { this.dishName = dishName; console.log(`GrillStation: Grilling ${dishName}.`); this.coordinator.notify(this, 'dishPrepared'); } } class BakeryStation { constructor(coordinator) { this.coordinator = coordinator; } bakeDish(dishName) { this.dishName = dishName; console.log(`BakeryStation: Baking ${dishName}.`); this.coordinator.notify(this, 'dishPrepared'); } } // Client Code const coordinator = new KitchenCoordinator(); const grillStation = new GrillStation(coordinator); const bakeryStation = new BakeryStation(coordinator); grillStation.prepareDish('Steak'); // Output: // GrillStation: Grilling Steak. // Coordinator: Notifying all stations that Steak is ready. bakeryStation.bakeDish('Bread'); // Output: // BakeryStation: Baking Bread. // Coordinator: Notifying all stations that Bread is ready.
로그인 후 복사

3. Command

The Command design pattern is an Object Behavioral Pattern that encapsulates the invocation of methods, requests, or operations into a single object and allows both parameterization and pass method calls that can be executed at our discretion. For example, look at how the head chef gives the command below.

// Command Interface class Command { execute() {} } // Concrete Commands class GrillCommand extends Command { constructor(grillStation, dishName) { super(); this.grillStation = grillStation; this.dishName = dishName; } execute() { this.grillStation.grill(this.dishName); } } class BakeCommand extends Command { constructor(bakeryStation, dishName) { super(); this.bakeryStation = bakeryStation; this.dishName = dishName; } execute() { this.bakeryStation.bake(this.dishName); } } // Receiver Classes class GrillStation { grill(dishName) { console.log(`GrillStation: Grilling ${dishName}.`); } } class BakeryStation { bake(dishName) { console.log(`BakeryStation: Baking ${dishName}.`); } } // Invoker Class class HeadChef { setCommand(command) { this.command = command; } executeCommand() { this.command.execute(); } } // Client Code const grillStation = new GrillStation(); const bakeryStation = new BakeryStation(); const grillCommand = new GrillCommand(grillStation, 'Steak'); const bakeCommand = new BakeCommand(bakeryStation, 'Bread'); const headChef = new HeadChef(); headChef.setCommand(grillCommand); headChef.executeCommand(); // GrillStation: Grilling Steak. headChef.setCommand(bakeCommand); headChef.executeCommand(); // BakeryStation: Baking Bread.
로그인 후 복사

Behavioral patterns can feel similar, so let's highlight their differences:

  • Observer: When a head chef prepares a dish, several other chefs are informed about it.

  • Mediator: A coordinator works in the kitchen, facilitating communication between various stations in the kitchen.

  • Command: The head chef issues commands to grill or bake dishes, encapsulating these actions as objects.

Design patterns give a clear way to fix common issues in software development much like a tidy kitchen and smart cooking methods lead to a good meal. When you get these patterns and put them to use, you make your coding easier and help your apps work better and grow more. It doesn't matter if you're new to coding or have done it for a long time - think of design patterns as trusted recipes passed down by many coders over the years. Try them out, play around with them, and soon you'll find that making strong apps becomes as natural as following a recipe you love. Happy coding!

위 내용은 코드 만들기: JavaScript 디자인 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!