js的一些设计模式概念记录

工厂模式

function createPerson(name, age, job) {
  let o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function() {
  console.log(this.name);
  };
  return o;
}
let person1 = createPerson("Nicholas", 29, "Software Engineer");
let person2 = createPerson("Greg", 27, "Doctor");

工厂模式可以解决创建多个类似对象的问题,但是没有解决对象标识问题

构造函数模式

function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function() {
  console.log(this.name);
  };
}
let person1 = new Person("Nicholas", 29, "Software Engineer");
let person2 = new Person("Greg", 27, "Doctor");
person1.sayName(); // Nicholas
person2.sayName(); // Greg

Person()构造函数代替了createPerson()工厂函数基本一样,但是有以下区别

  • 没有显示地创建对象
  • 属性和方法直接赋值给了this
  • 没有return

使用new操作符。以这种方式调用构造函数会执行如下操作
1.内存中创建一个新对象
2.这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性
3.构造函数内部的this被赋值为这个新对象(即this指向新对象)
4.执行构造函数内部的代码(给新对象添加属性)
5.如果构造函数返回非空对象,则返回该对象;否则返回刚创建的新对象。

构造函数模式解决了对象标识问题,但是没有解决在构造函数内部定义的方法会被多次实例化,不同实例上的函数虽然同名确不相同。

原型模式

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { 
 console.log(this.name); 
}; 
let person1 = new Person(); 
person1.sayName(); // "Nicholas" 
let person2 = new Person(); 
person2.sayName(); // "Nicholas" 
console.log(person1.sayName == person2.sayName); // true 

策略模式

策略模式是一种行为型设计模式,它允许我们定义一组算法,并将每个算法都封装起来,使它们可以互换使用。这样,我们可以在运行时动态地切换对象的算法。
下面是一个用JavaScript实现策略模式的例子,假设我们正在开发一个游戏,需要根据玩家的不同技能,计算不同的攻击力。我们可以使用策略模式来实现:

// 定义计算攻击力的策略类
class AttackStrategy {
  constructor() {}
  calculateAttack() {}
}

// 定义不同的计算攻击力的策略类
class BasicAttackStrategy extends AttackStrategy {
  constructor() {
    super();
  }
  calculateAttack() {
    return 10;
  }
}

class MagicAttackStrategy extends AttackStrategy {
  constructor() {
    super();
  }
  calculateAttack() {
    return 20;
  }
}

class SuperAttackStrategy extends AttackStrategy {
  constructor() {
    super();
  }
  calculateAttack() {
    return 50;
  }
}

// 定义玩家类
class Player {
  constructor(attackStrategy) {
    this.attackStrategy = attackStrategy;
  }
  attack() {
    return this.attackStrategy.calculateAttack();
  }
  setAttackStrategy(attackStrategy) {
    this.attackStrategy = attackStrategy;
  }
}

// 创建玩家对象
const player1 = new Player(new BasicAttackStrategy());
console.log(player1.attack()); // 输出 10

// 切换攻击策略
player1.setAttackStrategy(new MagicAttackStrategy());
console.log(player1.attack()); // 输出 20

// 切换攻击策略
player1.setAttackStrategy(new SuperAttackStrategy());
console.log(player1.attack()); // 输出 50

在这个例子中,我们定义了一个AttackStrategy策略类,并创建了三个不同的子类来计算攻击力。然后,我们定义了一个Player类,该类接受一个AttackStrategy对象作为参数,并且通过调用calculateAttack()方法来计算攻击力。最后,我们可以创建一个玩家对象,并根据需要切换不同的攻击策略。

这种方式下,我们可以轻松地添加新的攻击策略,而不需要修改Player类的代码。同时,我们也可以在运行时动态地切换攻击策略,从而获得更好的灵活性。

posted @   zeal666  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2021-03-09 伪类选择器和伪元素选择器的区别
点击右上角即可分享
微信分享提示