最近在学习设计模式,真的感觉它是一个很悬的东西,就看文本真的很难看懂,所以我就打算用最习惯的 JavaScript
的代码,通过实现 用户管理系统 这一统一场景下的不同功能,使用不同的设计模式来帮助理解。
本文中对设计模式的描述来自此文档,更详细的关于设计模式的说明也可参考:设计模式 | 菜鸟教程
创建型模式
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
单例模式(Singleton Pattern)
意图:确保一个类只有一个实例,并提供一个全局访问点。
应用场景:用户系统中的全局用户状态管理器,避免用户信息在多个模块中被重复创建。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class UserManager { static instance; constructor() { if (UserManager.instance) return UserManager.instance; this.users = new Map(); UserManager.instance = this; } addUser(id, name) { this.users.set(id, name); } }
const manager1 = new UserManager(); const manager2 = new UserManager(); console.log(manager1 === manager2);
|
工厂模式(Factory Pattern)
意图:通过工厂方法创建对象,避免直接使用 new
,使对象创建逻辑集中、灵活。
应用场景:在用户管理系统中,不同类型的用户(普通用户、管理员、游客)拥有不同的权限,我们可以通过工厂来统一创建用户对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class User { constructor(name) { this.name = name; this.role = 'user'; } }
class Admin { constructor(name) { this.name = name; this.role = 'admin'; } }
class Guest { constructor() { this.name = 'Guest'; this.role = 'guest'; } }
class UserFactory { static createUser(type, name) { switch (type) { case 'admin': return new Admin(name); case 'guest': return new Guest(); default: return new User(name); } } }
const admin = UserFactory.createUser('admin', 'Alice'); const guest = UserFactory.createUser('guest'); const user = UserFactory.createUser('user', 'Bob');
console.log(admin); console.log(guest); console.log(user);
|
抽象工厂模式(Abstract Factory Pattern)
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
应用场景:用户管理系统支持不同平台(Web 和 Mobile),不同平台上的用户组件(按钮、表单等)样式和行为不同,我们使用抽象工厂来统一创建它们。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| class WebButton { render() { console.log('渲染 Web 按钮'); } } class MobileButton { render() { console.log('渲染 Mobile 按钮'); } }
class WebForm { render() { console.log('渲染 Web 表单'); } } class MobileForm { render() { console.log('渲染 Mobile 表单'); } }
class UIFactory { createButton() {} createForm() {} }
class WebUIFactory extends UIFactory { createButton() { return new WebButton(); } createForm() { return new WebForm(); } }
class MobileUIFactory extends UIFactory { createButton() { return new MobileButton(); } createForm() { return new MobileForm(); } }
function renderUI(factory) { const button = factory.createButton(); const form = factory.createForm(); button.render(); form.render(); }
renderUI(new WebUIFactory());
renderUI(new MobileUIFactory());
|
建造者模式(Builder Pattern)
意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
应用场景:注册用户时,可以选择性添加信息,比如昵称、头像、邮箱等,构建过程灵活。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class UserProfile { constructor() { this.data = {}; } setName(name) { this.data.name = name; return this; } setAvatar(url) { this.data.avatar = url; return this; } setEmail(email) { this.data.email = email; return this; } build() { return this.data; } }
const profile = new UserProfile() .setName('Tom') .setAvatar('avatar.jpg') .setEmail('tom@example.com') .build();
console.log(profile);
|
原型模式(Prototype Pattern)
意图:通过复制已有对象来创建新对象,而不是通过类实例化。
应用场景:创建多个相似用户配置对象时,可以通过克隆的方式来快速复制。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const baseUser = { role: 'user', permissions: ['read'], clone() { return Object.assign({}, this); } };
const newUser = baseUser.clone(); newUser.name = 'Linda';
console.log(baseUser); console.log(newUser);
|
结构型模式
这些模式关注对象之间的组合和关系,旨在解决如何构建灵活且可复用的类和对象结构。
适配器模式(Adapter Pattern)
意图:将一个类的接口转换成客户端期望的另一个接口。
应用场景:接入第三方用户系统,其返回字段与本地不一致,需要转换格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const thirdUser = { uname: 'lucy', mail: 'lucy@mail.com' };
class LocalUser { constructor(name, email) { this.name = name; this.email = email; } }
class UserAdapter { static adapt(thirdData) { return new LocalUser(thirdData.uname, thirdData.mail); } }
const localUser = UserAdapter.adapt(thirdUser); console.log(localUser);
|
桥接模式(Bridge Pattern)
意图:将抽象与实现分离,使它们可以独立变化。
应用场景:用户通知模块支持多种发送方式(邮件、短信),不同平台用户可以使用不同方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class EmailSender { send(msg) { console.log('发送邮件:', msg); } } class SMSSender { send(msg) { console.log('发送短信:', msg); } }
class UserNotifier { constructor(sender) { this.sender = sender; } notify(message) { this.sender.send(message); } }
const emailNotifier = new UserNotifier(new EmailSender()); const smsNotifier = new UserNotifier(new SMSSender());
emailNotifier.notify('欢迎注册!'); smsNotifier.notify('验证码:123456');
|
过滤器模式(Filter、Criteria Pattern)
意图:使用不同标准来过滤一组对象,并可组合多个标准。
应用场景:用户列表筛选功能,如按是否激活、角色等条件组合过滤。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const users = [ { name: 'Tom', active: true, role: 'admin' }, { name: 'Lucy', active: false, role: 'user' }, { name: 'Mike', active: true, role: 'user' } ];
class ActiveFilter { filter(users) { return users.filter(u => u.active); } } class RoleFilter { constructor(role) { this.role = role; } filter(users) { return users.filter(u => u.role === this.role); } }
class AndFilter { constructor(...filters) { this.filters = filters; } filter(users) { return this.filters.reduce((result, f) => f.filter(result), users); } }
const activeUserFilter = new ActiveFilter(); const userRoleFilter = new RoleFilter('user'); const activeUsers = activeUserFilter.filter(users); const activeUserRole = new AndFilter(activeUserFilter, userRoleFilter).filter(users);
console.log(activeUsers); console.log(activeUserRole);
|
组合模式(Composite Pattern)
意图:将对象组合成树形结构以表示“部分-整体”的层次结构。
应用场景:权限管理系统中,角色可以由多个权限组合而成,甚至嵌套其他角色。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Permission { constructor(name) { this.name = name; } display(indent = '') { console.log(`${indent}- 权限:${this.name}`); } }
class Role { constructor(name) { this.name = name; this.children = []; } add(child) { this.children.push(child); } display(indent = '') { console.log(`${indent}+ 角色:${this.name}`); this.children.forEach(c => c.display(indent + ' ')); } }
const read = new Permission('read'); const write = new Permission('write'); const editor = new Role('Editor'); editor.add(read); editor.add(write);
const admin = new Role('Admin'); admin.add(editor); admin.add(new Permission('delete'));
admin.display();
|
装饰器模式(Decorator Pattern)
意图:动态添加对象的额外功能。
应用场景:用户行为增强,如登录加上日志记录或权限验证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class User { constructor(name) { this.name = name; } login() { console.log(`${this.name} 登录成功`); } }
function withLogging(user) { const originalLogin = user.login.bind(user); user.login = () => { console.log(`[LOG] ${user.name} 尝试登录`); originalLogin(); }; return user; }
const user = new User('Tom'); const enhancedUser = withLogging(user); enhancedUser.login();
|
外观模式(Facade Pattern)
意图:为子系统提供一个统一的高层接口,使子系统更易使用。
应用场景:用户注册流程中,涉及多个服务,如验证、存储、通知,通过外观简化调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Validator { static validate(user) { return !!user.name && !!user.email; } } class UserService { static save(user) { console.log('保存用户:', user); } } class Notifier { static notify(user) { console.log('发送欢迎邮件给:', user.email); } }
class RegisterFacade { static register(user) { if (!Validator.validate(user)) return console.log('注册失败:信息不完整'); UserService.save(user); Notifier.notify(user); } }
const newUser = { name: 'Tom', email: 'tom@mail.com' }; RegisterFacade.register(newUser);
|
享元模式(Flyweight Pattern)
意图:共享对象,减少内存使用,提高性能。
应用场景:大量用户头像使用相同样式,可以复用样式对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class AvatarStyle { constructor(color) { this.color = color; } }
class AvatarFactory { constructor() { this.cache = new Map(); } getStyle(color) { if (!this.cache.has(color)) { this.cache.set(color, new AvatarStyle(color)); } return this.cache.get(color); } }
const factory = new AvatarFactory(); const style1 = factory.getStyle('blue'); const style2 = factory.getStyle('blue'); console.log(style1 === style2);
|
代理模式(Proxy Pattern)
意图:为其他对象提供一个代理以控制访问。
应用场景:限制对敏感数据的访问,如用户管理界面中,普通用户不可查看 admin 信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const realUser = { name: 'admin', getSecret() { return '系统核心数据'; } };
const proxyUser = new Proxy(realUser, { get(target, prop) { if (prop === 'getSecret') { throw new Error('无权访问'); } return target[prop]; } });
try { console.log(proxyUser.getSecret()); } catch (e) { console.error(e.message); }
|
行为型模式
这些模式关注对象之间的通信和交互,旨在解决对象之间的责任分配和算法的封装。
好的,以下是用户管理系统场景下,继续补充的行为型设计模式示例:
责任链模式(Chain of Responsibility Pattern)
意图:将请求的发送者和接收者解耦,让多个对象有机会处理请求。形成一条处理链,沿着链传递请求,直到有对象处理它。
应用场景:用户注册流程中,依次执行验证用户名、邮箱、密码等规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| class Handler { setNext(handler) { this.next = handler; return handler; } handle(request) { if (this.next) return this.next.handle(request); return true; } }
class UsernameValidator extends Handler { handle(user) { if (!user.username) { console.log('用户名不能为空'); return false; } return super.handle(user); } }
class EmailValidator extends Handler { handle(user) { if (!user.email.includes('@')) { console.log('邮箱格式错误'); return false; } return super.handle(user); } }
class PasswordValidator extends Handler { handle(user) { if (user.password.length < 6) { console.log('密码长度不能少于6位'); return false; } return super.handle(user); } }
const user = { username: 'Tom', email: 'tom@example.com', password: '123456' }; const chain = new UsernameValidator(); chain.setNext(new EmailValidator()).setNext(new PasswordValidator());
chain.handle(user);
|
命令模式(Command Pattern)
意图:将请求封装成对象,从而使你可用不同的请求、队列或日志请求,并支持可撤销操作。
应用场景:管理员对用户执行批量操作(冻结、解冻、删除等)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Command { execute() {} }
class FreezeUserCommand extends Command { constructor(user) { super(); this.user = user; } execute() { console.log(`冻结用户:${this.user.name}`); } }
class DeleteUserCommand extends Command { constructor(user) { super(); this.user = user; } execute() { console.log(`删除用户:${this.user.name}`); } }
class AdminInvoker { constructor() { this.history = []; } run(command) { this.history.push(command); command.execute(); } }
const user = { name: 'Alice' }; const invoker = new AdminInvoker();
invoker.run(new FreezeUserCommand(user)); invoker.run(new DeleteUserCommand(user));
|
解释器模式(Interpreter Pattern)
意图:定义语言的语法,并构建一个解释器来解释语言中的句子。
应用场景:用户管理系统中,自定义查询语法解析,比如“role == ‘admin’ AND active == true”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Expression { interpret(context) {} }
class EqualsExpression extends Expression { constructor(key, value) { super(); this.key = key; this.value = value; } interpret(context) { return context[this.key] === this.value; } }
class AndExpression extends Expression { constructor(expr1, expr2) { super(); this.expr1 = expr1; this.expr2 = expr2; } interpret(context) { return this.expr1.interpret(context) && this.expr2.interpret(context); } }
const expr = new AndExpression( new EqualsExpression('role', 'admin'), new EqualsExpression('active', true) );
const user1 = { role: 'admin', active: true }; const user2 = { role: 'user', active: true };
console.log(expr.interpret(user1)); console.log(expr.interpret(user2));
|
迭代器模式(Iterator Pattern)
意图:提供一种方法顺序访问一个集合对象中的各个元素,而不暴露其内部表示。
应用场景:遍历用户列表的不同过滤条件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class UserCollection { constructor(users) { this.users = users; } createIterator() { let index = 0; const users = this.users; return { next: () => { if (index < users.length) { return { value: users[index++], done: false }; } return { done: true }; } }; } }
const users = [ { name: 'Tom' }, { name: 'Jerry' }, { name: 'Alice' } ];
const collection = new UserCollection(users); const iterator = collection.createIterator();
let result = iterator.next(); while (!result.done) { console.log(result.value.name); result = iterator.next(); }
|
意图:用一个中介对象封装一系列对象之间的交互。中介者使对象不需要显式地相互引用,从而使耦合松散。
应用场景:用户系统中,组件之间(如注册、通知、日志)通过中介通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| class Mediator { constructor() { this.components = {}; } register(name, component) { this.components[name] = component; component.setMediator(this); } notify(sender, event) { if (event === 'register') { this.components.logger.log('用户注册成功'); this.components.notifier.notify('欢迎新用户'); } } }
class Component { setMediator(mediator) { this.mediator = mediator; } }
class RegisterComponent extends Component { registerUser(name) { console.log(`注册用户:${name}`); this.mediator.notify(this, 'register'); } }
class LoggerComponent extends Component { log(message) { console.log(`[LOG]: ${message}`); } }
class NotifierComponent extends Component { notify(message) { console.log(`[通知]: ${message}`); } }
const mediator = new Mediator(); const register = new RegisterComponent(); const logger = new LoggerComponent(); const notifier = new NotifierComponent();
mediator.register('register', register); mediator.register('logger', logger); mediator.register('notifier', notifier);
register.registerUser('Linda');
|
备忘录模式(Memento Pattern)
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在之后恢复。
应用场景:编辑用户信息时支持撤销操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class User { constructor(name) { this.name = name; } save() { return new Memento(this.name); } restore(memento) { this.name = memento.getState(); } }
class Memento { constructor(state) { this.state = state; } getState() { return this.state; } }
class Caretaker { constructor() { this.history = []; } backup(memento) { this.history.push(memento); } undo() { return this.history.pop(); } }
const user = new User('Tom'); const caretaker = new Caretaker();
caretaker.backup(user.save()); user.name = 'Tommy';
console.log(user.name);
user.restore(caretaker.undo()); console.log(user.name);
|
观察者模式(Observer Pattern)
意图:当一个对象状态发生改变时,自动通知所有依赖它的对象。
应用场景:当用户状态变更时(如登录、登出),通知多个子系统同步更新状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Subject { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(o => o !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } }
class Logger { update(data) { console.log(`[Logger] 用户状态变更: ${data}`); } }
class UI { update(data) { console.log(`[UI] 更新界面,当前状态: ${data}`); } }
const userStatus = new Subject(); const logger = new Logger(); const ui = new UI();
userStatus.subscribe(logger); userStatus.subscribe(ui);
userStatus.notify('已登录');
|
状态模式(State Pattern)
意图:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
应用场景:根据用户的登录状态,切换系统对其的响应行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class LoggedOutState { handle() { console.log('请先登录'); } }
class LoggedInState { handle() { console.log('欢迎回来'); } }
class UserContext { constructor() { this.state = new LoggedOutState(); } setState(state) { this.state = state; } request() { this.state.handle(); } }
const user = new UserContext(); user.request(); user.setState(new LoggedInState()); user.request();
|
空对象模式(Null Object Pattern)
意图:用一个空对象来代替 null
,避免客户端做空判断。
应用场景:查询不到用户时返回一个空用户对象,避免后续代码出错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class RealUser { constructor(name) { this.name = name; } display() { console.log(`用户:${this.name}`); } }
class NullUser { display() { console.log('无此用户'); } }
function getUser(name) { const users = ['Tom', 'Alice']; if (users.includes(name)) return new RealUser(name); return new NullUser(); }
const user1 = getUser('Tom'); const user2 = getUser('John');
user1.display(); user2.display();
|
策略模式(Strategy Pattern)
意图:定义一系列算法,把它们封装起来,使它们可以互换。
应用场景:不同的用户登录方式(邮箱、手机号、第三方)通过策略切换处理逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class EmailStrategy { login(user) { console.log(`使用邮箱登录:${user.email}`); } }
class PhoneStrategy { login(user) { console.log(`使用手机号登录:${user.phone}`); } }
class LoginContext { setStrategy(strategy) { this.strategy = strategy; } login(user) { this.strategy.login(user); } }
const user = { email: 'a@example.com', phone: '123456789' }; const context = new LoginContext();
context.setStrategy(new EmailStrategy()); context.login(user);
context.setStrategy(new PhoneStrategy()); context.login(user);
|
模板方法模式(Template Pattern)
意图:在一个方法中定义算法的骨架,而将一些步骤延迟到子类中。
应用场景:不同用户注册流程类似,但某些步骤略有不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class UserRegistration { register() { this.inputInfo(); this.verifyIdentity(); this.save(); } inputInfo() { throw new Error('需要实现 inputInfo 方法'); } verifyIdentity() { console.log('默认身份验证'); } save() { console.log('保存用户信息'); } }
class GuestRegistration extends UserRegistration { inputInfo() { console.log('输入游客信息'); } }
class AdminRegistration extends UserRegistration { inputInfo() { console.log('输入管理员信息'); } verifyIdentity() { console.log('执行高级身份验证'); } }
new GuestRegistration().register(); new AdminRegistration().register();
|
访问者模式(Visitor Pattern)
意图:在不改变元素类的前提下定义作用于元素的新操作。
应用场景:对用户对象执行不同操作,比如导出信息、统计分析等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class User { constructor(name) { this.name = name; } accept(visitor) { visitor.visit(this); } }
class ExportVisitor { visit(user) { console.log(`导出用户信息:${user.name}`); } }
class StatsVisitor { visit(user) { console.log(`统计用户数据:${user.name}`); } }
const user = new User('Tom'); user.accept(new ExportVisitor()); user.accept(new StatsVisitor());
|
这些示例代码配合实际应用场景,应该能更好地帮助你理解设计模式的用途和写法。如果你希望我将这些内容整理成一个完整可复制的 Markdown 文档,我也可以继续处理。
你接下来是想整理输出所有模式,还是继续补充 J2EE 模式那部分?
J2EE 模式(表示层模式)
这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。
虽然这些模式源自 Java EE,但在现代前端/后端分离架构中依然有应用场景。
MVC 模式(Model-View-Controller Pattern)
意图:将数据(Model)、视图(View)和控制逻辑(Controller)分离,提高代码组织性。
应用场景:用户管理系统的前端页面组织。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class UserModel { constructor() { this.users = ['Tom', 'Alice']; } getUsers() { return this.users; } }
class UserView { render(users) { console.log('用户列表:', users.join(', ')); } }
class UserController { constructor(model, view) { this.model = model; this.view = view; } showUsers() { const users = this.model.getUsers(); this.view.render(users); } }
const model = new UserModel(); const view = new UserView(); const controller = new UserController(model, view);
controller.showUsers();
|
业务代表模式(Business Delegate Pattern)
意图:为表示层客户端提供统一访问业务服务的接口,减少表示层和业务层的耦合。
应用场景:页面组件通过统一接口访问用户服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class UserService { getUser(id) { return { id, name: 'Tom' }; } }
class BusinessDelegate { constructor() { this.userService = new UserService(); } getUser(id) { return this.userService.getUser(id); } }
class Client { constructor(delegate) { this.delegate = delegate; } showUser(id) { const user = this.delegate.getUser(id); console.log('用户信息:', user); } }
const delegate = new BusinessDelegate(); const client = new Client(delegate); client.showUser(1);
|
组合实体模式(Composite Entity Pattern)
意图:用于表示一个由多个对象组成的复杂数据模型。
应用场景:一个用户对象包括多个子对象,如基本信息、权限、设置等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class UserInfo { constructor(name) { this.name = name; } }
class UserSetting { constructor(theme) { this.theme = theme; } }
class UserCompositeEntity { constructor(name, theme) { this.userInfo = new UserInfo(name); this.userSetting = new UserSetting(theme); } getData() { return { name: this.userInfo.name, theme: this.userSetting.theme }; } }
const userEntity = new UserCompositeEntity('Alice', 'dark'); console.log(userEntity.getData());
|
数据访问对象模式(DAO Pattern)
意图:将数据库操作和业务逻辑分离,封装对数据源的访问。
应用场景:封装用户数据的读写逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class UserDAO { constructor() { this.users = new Map(); } save(user) { this.users.set(user.id, user); } find(id) { return this.users.get(id); } }
const dao = new UserDAO(); dao.save({ id: 1, name: 'Tom' }); console.log(dao.find(1));
|
前端控制器模式(Front Controller Pattern)
意图:提供单一入口处理请求,统一处理认证、日志等。
应用场景:前端路由或 API 请求的统一入口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Dispatcher { dispatch(request) { console.log(`处理请求:${request}`); } }
class FrontController { constructor() { this.dispatcher = new Dispatcher(); } handleRequest(request) { console.log('日志记录:', request); this.dispatcher.dispatch(request); } }
const controller = new FrontController(); controller.handleRequest('查看用户列表');
|
拦截过滤器模式(Intercepting Filter Pattern)
意图:在请求到达目标对象前进行预处理,如认证、日志记录。
应用场景:在访问用户数据前执行权限校验。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class AuthFilter { execute(request) { console.log(`权限检查:${request}`); } }
class LogFilter { execute(request) { console.log(`请求日志:${request}`); } }
class FilterChain { constructor() { this.filters = []; this.target = null; } addFilter(filter) { this.filters.push(filter); } setTarget(target) { this.target = target; } execute(request) { this.filters.forEach(f => f.execute(request)); this.target.execute(request); } }
class Target { execute(request) { console.log(`处理请求:${request}`); } }
const filterChain = new FilterChain(); filterChain.addFilter(new AuthFilter()); filterChain.addFilter(new LogFilter()); filterChain.setTarget(new Target());
filterChain.execute('删除用户');
|
服务定位器模式(Service Locator Pattern)
意图:隐藏服务的创建逻辑,通过名称查找服务。
应用场景:统一注册和查找服务,如用户服务、日志服务等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class ServiceLocator { constructor() { this.services = new Map(); } register(name, service) { this.services.set(name, service); } getService(name) { return this.services.get(name); } }
class UserService { execute() { console.log('执行用户服务'); } }
const locator = new ServiceLocator(); locator.register('userService', new UserService()); locator.getService('userService').execute();
|
传输对象模式(Transfer Object Pattern)
意图:使用简单对象封装数据,用于网络或模块之间传输。
应用场景:用户模块将用户数据封装为 DTO(Data Transfer Object)传给其他模块或前端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class UserDTO { constructor(id, name) { this.id = id; this.name = name; } }
class UserService { getUserDTO() { return new UserDTO(1, 'Tom'); } }
const service = new UserService(); const userDTO = service.getUserDTO(); console.log('传输对象:', userDTO);
|
总结
本文中,围绕「用户管理系统」这个通用的业务场景,通过 JavaScript
代码演示了讲解了 23 种 GoF 设计模式 和 8 种 J2EE 模式,并结合 JavaScript 示例进行了实际演示。通过对设计模式的学习我们可以知道:
设计模式不是框架,而是思想
每种模式的本质都是为了解决「重复出现的结构性问题」,它们不是强制要套的模板,而是我们在构建复杂系统时总结出的经验智慧。学习设计模式,是尝试去理解他们而不是死记硬背,这才是学习设计模式的关键。
场景驱动,理解更深
设计模式真的很难通过语言来讲述,所以这篇文章才尝试着以用户管理为例,无论是添加用户、展示用户列表,还是用户的登录认证、权限控制、服务抽象……都有对应的设计模式提供灵感和规范。把设计模式用在实际业务中,才真正理解它的价值。
JS 不是静态语言,也可以优雅地使用模式
虽然 JavaScript 是动态语言,很多时候我们不用过度抽象,但设计模式依然能提升可读性、复用性和协作性。通过对象组合、闭包、类等手段,同样可以表达出清晰的结构和职责分离。
最后,列出一张简单的总览表吧:
类别 |
模式名称 |
主要意图 |
应用场景 |
创建型 |
单例模式 (Singleton) |
保证一个类只有一个实例 |
全局配置、缓存、数据库连接、用户状态管理 |
|
工厂模式 (Factory) |
创建对象由工厂统一管理 |
用户角色创建、日志系统、插件系统 |
|
抽象工厂 (Abstract Factory) |
创建一族相关对象,保持产品一致性 |
UI 组件库(按钮 + 表单)、多平台适配 |
|
建造者模式 (Builder) |
将复杂对象的构建过程封装,使构建与表示分离 |
用户注册配置、表单配置生成器 |
|
原型模式 (Prototype) |
通过克隆已有对象创建新对象 |
克隆用户模板、复制设置项 |
结构型 |
适配器模式 (Adapter) |
统一接口格式,实现兼容 |
第三方 API 接入、老旧系统接口兼容 |
|
桥接模式 (Bridge) |
分离抽象与实现,解耦变化 |
消息发送(文本/图像)+ 渠道(微信/邮件) |
|
过滤器模式 (Filter/Criteria) |
使用多个标准过滤数据集合 |
用户搜索筛选、数据权限过滤 |
|
组合模式 (Composite) |
将对象组合成树形结构,统一处理单个对象与组合对象 |
权限树、组织架构、菜单系统 |
|
装饰器模式 (Decorator) |
动态添加行为,不修改原对象 |
登录功能增强、日志记录、数据校验 |
|
外观模式 (Facade) |
提供统一接口,简化系统使用 |
用户注册流程封装、复杂子系统统一调用 |
|
享元模式 (Flyweight) |
共享相似对象,节省内存 |
用户列表头像复用、大量标签复用 |
|
代理模式 (Proxy) |
控制对象访问,可添加权限、延迟加载等功能 |
权限代理、缓存代理、懒加载图像 |
行为型 |
责任链模式 (Chain of Resp.) |
请求沿链传递,直到某个对象处理 |
表单校验链、权限处理链 |
|
命令模式 (Command) |
将请求封装成对象,支持撤销、排队等操作 |
操作历史、按钮动作、任务调度 |
|
解释器模式 (Interpreter) |
定义语言语法,解释表达式 |
表达式解析器、权限规则 DSL |
|
迭代器模式 (Iterator) |
按序访问集合元素,隐藏内部实现 |
用户分页浏览、日志遍历 |
|
中介者模式 (Mediator) |
对象通过中介解耦通信 |
聊天系统、组件交互协调 |
|
备忘录模式 (Memento) |
保存和恢复对象状态 |
表单状态保存、草稿功能 |
|
观察者模式 (Observer) |
一对多依赖,状态变化通知所有观察者 |
登录状态广播、数据变更通知 |
|
状态模式 (State) |
对象行为随状态变化 |
用户账号状态(禁用/激活)、审批流程 |
|
空对象模式 (Null Object) |
提供默认无操作对象,避免 null 判断 |
默认用户、日志记录器空实现 |
|
策略模式 (Strategy) |
定义一系列算法或行为,动态替换 |
登录策略、计费方式、过滤条件 |
|
模板方法模式 (Template) |
定义算法骨架,子类实现具体步骤 |
表单提交流程、导出流程 |
|
访问者模式 (Visitor) |
封装对对象结构的操作,增加新行为无需修改结构 |
用户报告生成器、元素批量处理 |
J2EE 模式 |
MVC 模式 |
分离模型、视图、控制器 |
Web 应用架构、Vue/React 应用 |
|
业务代表模式 |
屏蔽表示层和业务层之间的交互细节 |
封装 API 请求层 |
|
组合实体模式 |
使用组合实体表示依赖关系的数据模型 |
复杂用户资料管理 |
|
DAO 模式 |
抽象和封装数据访问逻辑 |
封装数据库查询、用户持久化 |
|
前端控制器模式 |
统一请求处理入口 |
单页应用路由、请求中间层 |
|
拦截过滤器模式 |
预处理/后处理请求 |
登录验证、日志、XSS 过滤 |
|
服务定位器模式 |
查找服务对象,隐藏查找逻辑 |
动态依赖注入、插件定位 |
|
传输对象模式 |
使用对象封装数据传输内容 |
用户 DTO、前后端传参结构 |