设计模式是针对常见软件问题的高级面向对象解决方案。模式是关于对象的可重用设计和交互。在讨论复杂的设计解决方案时,每个模式都有一个名称并成为词汇表的一部分。本文主要介绍几种常见的设计模式。大多数情况下,它们遵循原始图案设计的结构和意图。这些示例演示了每种模式背后的原则,但并未针对 JavaScript 进行优化。
//堆代码 duidaima.com function Employee(name) { this.name = name; this.say = function () { console.log("I am employee " + name); }; } function EmployeeFactory() { this.create = function (name) { return new Employee(name); }; } function Vendor(name) { this.name = name; this.say = function () { console.log("I am vendor " + name); }; } function VendorFactory() { this.create = function (name) { return new Vendor(name); }; } function run() { var persons = []; var employeeFactory = new EmployeeFactory(); var vendorFactory = new VendorFactory(); persons.push(employeeFactory.create("Joan DiSilva")); persons.push(employeeFactory.create("Tim O'Neill")); persons.push(vendorFactory.create("Gerald Watson")); persons.push(vendorFactory.create("Nicole McNight")); for (var i = 0, len = persons.length; i < len; i++) { persons[i].say(); } }02.Builder (建造者模式)
function Shop() { this.construct = function (builder) { builder.step1(); builder.step2(); return builder.get(); } } function CarBuilder() { this.car = null; this.step1 = function () { this.car = new Car(); }; this.step2 = function () { this.car.addParts(); }; this.get = function () { return this.car; }; } function TruckBuilder() { this.truck = null; this.step1 = function () { this.truck = new Truck(); }; this.step2 = function () { this.truck.addParts(); }; this.get = function () { return this.truck; }; } function Car() { this.doors = 0; this.addParts = function () { this.doors = 4; }; this.say = function () { console.log("I am a " + this.doors + "-door car"); }; } function Truck() { this.doors = 0; this.addParts = function () { this.doors = 2; }; this.say = function () { console.log("I am a " + this.doors + "-door truck"); }; } function run() { var shop = new Shop(); var carBuilder = new CarBuilder(); var truckBuilder = new TruckBuilder(); var car = shop.construct(carBuilder); var truck = shop.construct(truckBuilder); car.say(); truck.say(); }03、Factory Method (工厂方法)
var Factory = function () { this.createEmployee = function (type) { var employee; if (type === "fulltime") { employee = new FullTime(); } else if (type === "parttime") { employee = new PartTime(); } else if (type === "temporary") { employee = new Temporary(); } else if (type === "contractor") { employee = new Contractor(); } employee.type = type; employee.say = function () { console.log(this.type + ": rate " + this.hourly + "/hour"); } return employee; } } var FullTime = function () { this.hourly = "$12"; }; var PartTime = function () { this.hourly = "$11"; }; var Temporary = function () { this.hourly = "$10"; }; var Contractor = function () { this.hourly = "$15"; }; function run() { var employees = []; var factory = new Factory(); employees.push(factory.createEmployee("fulltime")); employees.push(factory.createEmployee("parttime")); employees.push(factory.createEmployee("temporary")); employees.push(factory.createEmployee("contractor")); for (var i = 0, len = employees.length; i < len; i++) { employees[i].say(); } }04、Adapter(适配器模式)
// old interface function Shipping() { this.request = function (zipStart, zipEnd, weight) { // ... return "$49.75"; } } // new interface function AdvancedShipping() { this.login = function (credentials) { /* ... */ }; this.setStart = function (start) { /* ... */ }; this.setDestination = function (destination) { /* ... */ }; this.calculate = function (weight) { return "$39.50"; }; } // adapter interface function ShippingAdapter(credentials) { var shipping = new AdvancedShipping(); shipping.login(credentials); return { request: function (zipStart, zipEnd, weight) { shipping.setStart(zipStart); shipping.setDestination(zipEnd); return shipping.calculate(weight); } }; } function run() { var shipping = new Shipping(); var credentials = { token: "30a8-6ee1" }; var adapter = new ShippingAdapter(credentials); // original shipping object and interface var cost = shipping.request("78701", "10010", "2 lbs"); console.log("Old cost: " + cost); // new shipping object with adapted interface cost = adapter.request("78701", "10010", "2 lbs"); console.log("New cost: " + cost); }