设计模式 5 大原则
1,单一职责原则
一个类只封装一定的功能
过于复杂的代码块想办法拆分成单独的方法
2,开闭原则
对修改关闭,对扩展开放
增加或者变更需求时,不应该修改核心代码,应该再之前的基础上新增功能
3,里氏替换原则
父类能用的地方,子类都能用,即可以用任何子类替换父类
4,接口隔离原则
接口之间功能不要重复
接口更纯粹干净
5,依赖倒置原则
使用方应该依赖抽象,比如接口,抽象类,配置等,而不是其实现,因为实现会频繁变更
设计模式分类
1,创建型
1,单例模式
一个类只有一个全局实例,并提供一个获取它的全局入口。
class LoginForm {
constructor() {
}
}
//用闭包存一个永久的单例
LoginForm.getInstance = (function () {
let instance = null
return = function () {
if (!instence) {
instance = new LoginForm()
}
return instance
}
})()
2,工厂模式
如果不想让某个子系统与较大的哪个对象之间形成强耦合。而是想在运行时可以从许多系统进行挑选或者切换的话。工厂模式可以进行解耦。
class product1 {
run () { }
}
class product2 {
run () { }
}
class Fatory {
}
Fatory.create(productName) {
if (productName === '1') {
return new product1()
}
else {
return new product2()
}
}
let p = Fatory.create('1')
p.run()
2,结构型
1,适配器模式
适配器用于解决两个接口不兼容的情况,通过适配器可以在不改变原有接口源码的情况下,让两个不兼容的接口通信
//客户端接收一个对象,必须有run方法
class client {
constructor(app) {
this.app = app
}
run () {
this.app.run()
}
}
//appForien没有run方法,无法与client兼容
class appForien {
constructor(name) {
this.name
}
business () {
return this.name
}
}
//创建Forien适配器
class forienAdapter {
constructor(app) {
this.app = app
}
run () {
const result = this.app.business()
return result
}
}
//使用
const app = new appForien()
const fa=new forienAdapter(app)
const c = new client(fa)
c.run()
应用场景:vue中的computed就是适配器,将原先各种数据组装成客户端能用的新数据
2,装饰器模式
动态的给对象或者函数添加某些功能
class cellPhone {
create () {
}
}
class Decorator {
constructor(cellPhone, funcBefore, funcAfter) {
this.cellPhone = cellPhone
}
create () {
funcBefore()
this.cellPhone.create()
funcAfter()
}
}
//使用
const d = new Decorator(new cellPhone(), () => {
//前置功能
}
, () => {
//后置功能
})
d.create()
3,代理模式
客户端不直接与接口进行通信,而是加一个代理层进行通讯
class client {
constructor() {
this.msg = ''
}
getMsg () {
return this.msg
}
setMsg (msg) {
this.msg = msg
}
}
class msgProxy {
constructor(client, encodeMsg) {
this.client = client
this.encodeMsg = encodeMsg
}
getMsg () {
return this.encodeMsg(this.client.getMsg())
}
setMsg (msg) {
const msgStr = this.encodeMsg(msg)
this.client.setMsg(msgStr)
}
}
//使用
const c = new client()
const p = new msgProxy(c, (str) => {
return str + '111'
})
p.setMsg('aaa')
console.log(p.getMsg())
4,组合模式
3,行为型
1,观察者模式
定义了一种一对多的模式。有多个观察者监听一个主题,只要主题发送通知,所有观察者都会进行响应。
这其中的关键是主题要收集到所有的观察者。然后有一个通知方法,循环遍历通知每一个观察者。对于观察者而言,他们有一个依赖的
主题,并且有一个同名的响应方法。
//一个主题,用于收集依赖,发布通知
class Subject {
constructor() {
this.state = 0
this.observers = []
}
getState () {
return this.state
}
setState (state) {
this.state = state
this.notifyAllObservers()
}
notifyAllObservers () {
this.observers.forEach(ob => {
ob.update()
})
}
attach (observer) {
this.observers.push(observer)
}
}
//观察者,用于跟踪主题,响应通知
class Observer{
constructor(name,subject){
this.name = name
this.subject = subject
this.subject.attach(this)
}
update(){
//do something
}
}
2,迭代器模式
提供一种方法顺序执行一个聚合对象中各个元素,而又不暴露该对象得内部表示
class Iterator {
constructor(container) {
this.list = container.list
this.index = 0
}
next () {
if (this.hasNext()) {
//do something
return this.list[this.index++]
}
return null
}
hasNext () {
return this.index >= this.list.length
}
}
class Container{
constructor(list){
this.list = list
}
getIterator(){
return new Iterator(this)
}
}
//使用
const con = new container([1,2,3,4,5])
let iterator = con.getIterator()
while(iterator.hasNext()){
iterator.next()
}
3,策略模式
将不同的可能用到的方法封装在一起,并且他们可以互相替换
//应用场景:表单验证
//策略对象
class strategies {
static isRequire (value, errorMsg) {
if (!value) {
console.log(errorMsg)
}
}
static minLength (value, errorMsg, length) {
if (value.length < length) {
console.log(errorMsg)
}
}
}
//验证类
class Validator {
constructor(form) {
this.form = form
}
valid (rules) {
rules.forEach(rule => {
rule.stratege(form[rule.name], rule.errorMsg,rule.args)
});
}
}
//使用,配置策略
const rules = [
{ name: id, stratege: strategies.isRequire, errorMsg: '必填' },
{ name: address, stratege: strategies.minLength, errorMsg: '过长', args: 10 },
]
const formValidator = new Validator({
id:'123',
address:'tom jack no 100'
}).valid(rules)
4,模板方法模式
将一个过程或者一个流程算法的公共部分提取出来,可变部分的逻辑给子类去实现和变动,整个大步骤不变
class flow{
constructor(step1,step2){
this.step1=step1
this.step2=step2
}
run(){
this.start()
this.step1()
this.step2()
this.end()
}
start(){
console.log('start')
}
end(){
console.log('end')
}
}
5,命令模式
将执行逻辑和执行对象之间解耦,使得执行逻辑可以更容易扩展
//接收器
class Receiver {
run () {
console.log('run start')
}
}
//命令类型
class Command {
constructor(Receiver) {
this.Receiver = Receiver
}
execute () {
this.Receiver.run()
}
}
//命令触发器
class Invoker {
constructor(Command) {
this.Command = Command
}
invoke () {
this.Command.execute()
}
}
//使用,客户下订单发货
const base = new Receiver() //仓库
const order = new Command(base) //订单
const client = new Invoker(order) //客户
//客户下订单
client.invoke()
6,中介模式
将多个对象的直接交互,变成由一个中介对象来间接交互,可以将交互对象之间解耦
class A {
constructor() {
this.val = ''
}
setB (m, val) {
m.setB(val)
}
}
class B {
constructor() {
this.val = ''
}
setA (m, val) {
m.setA(val)
}
}
//中介者
class Mediator {
constructor(a, b) {
this.a = a
this.b = b
}
setA (val) {
A.val = val
}
setB (val) {
A.val = val
}
}