模板方法模式在一个方法中 定义一个算法的骨架,而将一些步骤的实现 延迟到子类 中:
- 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤的具体实现;
- 一般有两部分组成,第一部分是 抽象父类,第二部分是具体的 实现子类;
适用场景:
- 父类视角:一次性 实现 一个算法 不变的部分,并将 可变部分 留给 子类 实现;
- 子类视角:各个子类中,公共部分 被提取出来,集中到一个公共的父类中,避免代码重复;
优点:
- 提高代码复用性:将 相同部分代码,放在抽象的父类中;
- 提高扩展型:将 不同的代码,放在 不同的子类中,通过对子类的扩展,增加新的行为;
- 符合开闭原则:通过 父类 调用 子类 的操作,通过 对子类的扩展 来 增加新的行为;
缺点:
- 增加复杂性:类 数量增加,增加了 系统复杂性; 引入了抽象类,对于每个实现,都需要定义一个子类;
- 继承缺点:模板方法主要 通过 继承实现,继承关系自身就有缺点,如果父类增加新的抽象方法,所有的子类都要修改一遍;
类图
代码
abstract class Person {
dinner() {
this.buy();
this.cook();
this.eat();
}
abstract buy();
abstract cook();
abstract eat();
}
class Zhangsan extends Person {
buy() { console.log('买黄瓜'); }
cook() { console.log('拍黄瓜'); }
eat() { console.log('吃黄瓜'); }
}
let zhangsan = new Zhangsan();
zhangsan.dinner();
场景
dialog
HTML
js
css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="3.css">
</head>
<body>
</body>
<script src="3.js"></script>
<script>
let dialog = new ConfirmDialog({
title: '标题',
content: '内容'
});
</script>
</html>
class Dialog {
constructor(options) {
this.title = options.title || '标题';
this.content = options.content || '内容';
this.onConfirm = options.onConfirm || this.hide;
this.onCancel = options.onCancel || this.hide;
this.init();
this.initEventHandler();
}
init() {
this.panel = document.createElement('div');
this.panel.className = 'dialog';
this.titleP = document.createElement('p');
this.titleP.innerHTML = this.title;
this.panel.appendChild(this.titleP);
this.contentP = document.createElement('p');
this.contentP.innerHTML = this.content;
this.panel.appendChild(this.contentP);
this.confirmBtn = document.createElement('button');
this.confirmBtn.className = 'button confirm-button';
this.confirmBtn.innerHTML = '确定';
this.panel.appendChild(this.confirmBtn);
this.cancelBtn = document.createElement('button');
this.cancelBtn.className = 'button cancel-button';
this.cancelBtn.innerHTML = '取消';
this.panel.appendChild(this.cancelBtn);
document.body.appendChild(this.panel);
}
initEventHandler() {
this.cancelBtn.addEventListener('click', () => {
this.onCancel();
this.hide();
});
}
show() {
this.panel.style.display = 'block';
}
hide() {
this.panel.style.display = 'none';
}
}
// 第一种弹窗
class ContentDialog extends Dialog {
init() {
super.init();
this.titleP.parentNode.removeChild(this.titleP);
}
}
// 第二种弹窗
class ConfirmDialog extends Dialog {
init() {
super.init();
this.cancelBtn.parentNode.removeChild(this.cancelBtn);
}
}
.dialog {
width : 400px;
height : 300px;
position : absolute;
padding : 20px;
top : 50%;
left : 50%;
margin-left : -200px;
margin-top : -150px;
border : 1px solid#000;
background-color: #EEE;
border-radius : 5px;
display : flex;
flex-direction : column;
align-items : center;
justify-content : center;
}
.dialog button {
width : 100px;
height : 30px;
position: absolute;
border : none;
outline : none;
}
.dialog .confirm-button {
right : 140px;
bottom: 20px;
}
.dialog .cancel-button {
right : 20px;
bottom: 20px;
}
生命周期的设计原理
打赏作者
您的打赏是我前进的动力
微信
支付宝
享元模式
上一篇
评论