代码的可扩展性是什么?
你是否遇到过如下的问题:
1,写好了方法,后来发现这个方法好像不够用,又回头去改方法。
2,写好了功能,产品跑过来,这里改个啥啥啥,又去大量改动原有代码
代码可扩展性的目的:面对需求变更,方便需求更改。减少代码修改的难度。
有哪些让我们更好扩展的设计模式:装饰者模式和适配器模式,更好的更改方法。装饰者模式,它关注的是功能,方法,当你的功能方法不满足我的时候。而适配器模式,它关注的是整个模块,当我们这个模块,需要一些API,方便我们另外一个模块去使用。一个关注的是内部的需求,一个关注的是外部的接口。
装饰者模式
装饰者模式基本了解:
function a() {
console.log(1);
}
function b() {
a(); //可以用继承的方法,但是会有點笨重
console.log(2)
}
假设现在,所以的请求都需要一个loding
$.ajax();
var ajax = $.ajax;
$.ajax = function () {
ajax.call(this);
loading();
};
$.ajax(); //经过装饰者模式,所以的ajax方法都会加上 loading 这个方法
假设接手了一个老项目,这个老项目的代码非常难改
dom1.onclick = function () {
console.log(1);
};
var oldFn = dom1.onclick;
dom1.onclick = function () {
oldFn();
console.log(2);
};
假设我们在编写一个飞机大战的游戏,随着经验值的增加,我们操作的飞机对象可以升级成更厉害的飞机,一开始这些飞机只能发射普通的子弹,升到第二级时可以发射导弹,升到第三级时可以发射原子弹。
var plane = {
fire: function(){
console.log( '发射普通子弹' );
}
}
var missileDecorator = function(){
console.log( '发射导弹' );
}
var atomDecorator = function(){
console.log( '发射原子弹' );
}
var fire1 = plane.fire;
plane.fire = function(){
fire1();
missileDecorator();
}
var fire2 = plane.fire;
plane.fire = function(){
fire2();
atomDecorator();
}
plane.fire();
// 分别输出: 发射普通子弹、发射导弹、发射原子弹
使用AOP实现装饰者模式 AOP实现装饰者模式
适配器模式
它可以形象的描述为我们现实生活中的手机充电接口转换器。
function dog() { //假设有狗这么一个类
};
dog.prototype.shout = function () { //然后它有叫的方法
};
dog.prototype.run = function () { //而且它还有跑的方法
};
function bird() { //我们还有一个鸟的类
}
bird.prototype.shout = function () { //鸟也可以叫
};
bird.prototype.fly = function () { //但它不是跑的方法,而是飞的方法
};
现在有一个特别新奇的方法,就想让狗有飞起来的方法,意思就是让狗调用这个接口,但狗没有,即接口不适配
dog.prototype.fly //可以给类添加fly方法,这样不好,修改了它的类。
function dogAdapter(dogob) { //通过一个中介类,既适配器
this.dogob = dogob; //这个适配器会接触一个狗的实例化对象
};
dogAdapter.prototype = new bird();
总结:有两个对象,api、参数不满足的时候,可以通过一个中介的适配器,来转化接口。
使用场景
假设公司之前用jquery框架,现在用自己开发的框架A。这两个框架之间非常相似,但是有两个方法不同。jquery获取css是 .on,我们是 A.o。怎么办?
function myA() { //新建一个适配器
A.call(this); //适配器继承 A,用简单点的继承
};
myA.prototype = A.prototype; //这样的继承是由问题的,不推荐,这里是图方便
myA.prototype.css = function () {
A.c.call(this, arguments);
// this.c.call(this,arguments); //这样也是可以的
};
myA.prototype.on = function () {
A.o.call(this, arguments);
};
window.$ = myA;
更好的应对需求改变:职责链模式、观察者模式。
观察者模式
观察者模式是为了去解决一个深入的解耦代码之间的模块,从而达到应对需求改变的需要。
观察者模式的基本架构:
// 中介观察者,独立于任何模块,但是它可以通知到人
var Observer = { //先定义一个观察者对象
_message: {}, //各个的消息订阅
regist: function () {
// 订阅消息
},
fire: function () {
//触发消息
},
remove: function () {
//删除消息
}
}
方便我们需求变更,最核心的其实就是三个字: 低耦合。其实不管是订阅者模式、职责链模式、
还是观察者模式也好,都是为了把我们模块之间的耦合度变得更低。
高耦合示例:
// 模块1 里面嵌套模块2 ,嵌套的很深,代码耦合的很紧
function mode1() {
function mode2() {
};
mode2();
}
改成低耦合:
function mode1() {
Observer.regist("mode1sendmode2");
Observer.fire("mode1sendmode2");
};
function mode2() {
};
职责链模式
了解前端负责人的工作内容
如何做架构
架构总览
程序:本质是数据结构+算法,通俗理解就是模块+消息交流。
架构师是做什么的
- 规范-有效的规范团队工作形式
- 架构-就是划分出低耦合的模块,并高效的设计模块间的交流。
宏观架构图示:
如何分析业务架构:
- 从需求出发划分
- 需求做的事情不能多不能少
架构模板: