这是我参与 8 月更文挑战的第 10 天,活动详情查看: 8月更文挑战
前言
今天我们主要来聊聊设计模式中的结构型模式。
适配器模式(Adapter Pattern)
适配器模式可用来在现有接口和不兼容的类之间进行适配,使用这种模式的对象又叫包装器。像日常业务开发过程中,需要和后端对接接口,然后再实现自身的业务逻辑。但是当后端API规格发生变化的时候,我们可能需要又改接口又改业务逻辑,整体将变得不可控。这时候,使用适配器模式就可以解决这一问题。
function getList() { // 请求后端API,并实现前端逻辑
fetch('/api').then((res) => {
const data = Adapter(res.data);
// TODO
})
}
function Adapter(data) {
for() {
// TODO
}
return data
}
复制代码
当后端API发生调整的时候,我们只需要调整适配器代码Adapter,而不需要改动业务逻辑代码。
桥接模式(Bridge Pattern)
将抽象部分与它的实现部分分离,使他们都可以独立的变化。 也就是说,桥接模式里面有两个角色:
- 扩充抽象类
- 具体实现类
最简单的桥接模式:
var each = function (arr, fn) {
for (var i = 0; i < arr.length; i++) {
var val = arr[i];
if (fn.call(val, i, val, arr)) {
return false;
}
}
};
var arr = [1, 2, 3, 4];
each(arr, function (i, v) {
arr[i] = v * 2;
});
复制代码
each函数是一个抽象类,而fn函数则是具体的实现,在这段代码中,抽象部分和实现部分的更改是互不影响的,可以独立的改变,所以,这个例子虽然简单,但是是一个典型的桥接模式的应用。
过滤器模式(Filter、Criteria Pattern)
这种模式Javascript已经实现了,就是我们经常用的filter函数
[1, 2, 3].filter((currentValue,index,arr) => true)
复制代码
- currentValue:必须。当前元素的值
- index:可选。当前元素的索引值
- arr:可选。当前元素属于的数组对象
组合模式(Composite Pattern)
像一般的面向对象语言,都会实现继承这个特性,但比如像Go,需要通过组合而并非继承。继承这种模式有很多弊端,因为和本章讨论内容无关,这里就不再赘述。这种模式在写Vue、React的时候接触的会比较多,可能你自己都没有意识到这是一种组合模式。
function render() {
return (
<div>
<A />
<B />
</div>
)
}
复制代码
组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性。
装饰器模式(Decorator Pattern)
大家应该使用过mixin(混入)功能,在Vue、React中也有出现。装饰器是旨在提升重用性能的一种结构性设计模式。
它们能够被用来在不需要深度改变使用它们的对象的依赖代码的前提下,变更我们希望向其中附加功能的现有系统之中。开发者使用它们的一个通常的理由是,它们的应用程序也许包含了需要大量彼此不相干类型对象的特性。想象一下不得不要去定义上百个不同对象的构造器,比方说,一个Javascript游戏。
javascript语言动态改变对象相当容易,可以直接改写对象或者对象的某个方法
Function.prototype.before = function( beforefn ){
var __self = this; // 保存原函数的引用
return function(){ // 返回包含了原函数和新函数的"代理"函数
beforefn.apply( this, arguments ); // 执行新函数,且保证 this 不被劫持,新函数接受的参数
// 也会被原封不动地传入原函数,新函数在原函数之前执行
return __self.apply( this, arguments ); // 执行原函数并返回原函数的执行结果,
// 并且保证 this 不被劫持
}
}
Function.prototype.after = function( afterfn ){
var __self = this;
return function(){
var ret = __self.apply( this, arguments );
afterfn.apply( this, arguments );
return ret;
}
};
work.after(function(){
console.log('work:17:00 - 21:00')
})
复制代码
最后打波小广告,美团校招社招内推,不限部门,不限岗位,不限投递数量,海量hc,快来快来~