设计模式有很多,这些设计模式的出现是由准则或者说有根据的,不是平白无故出现的,下面我们就来认识一下这些设计原则。

在此以前,我想说一下,看这篇文章的读者应该都是前端工程师或者使用JS编程语言的程序员,为了结合JS语言的特性(弱类型,无接口等)有一些原则只是简单的说一下,在JS中基本不会使用,只需要你了解。

如果想要全面学习设计原则以及23种设计模式,应该选择Java而不是JS。我们只针对JS语言和前端过程中可以使用到的一些设计原则。

1  单一职责原则(S):一个程序只做一件事,如果事情过于复杂,那么就应该拆开,使得每一部分保持独立。

开发封闭原则(0):对修改封闭,对扩展开发。在遇到新的需求增加时,应该扩展新代码而不是修改原来的代码。

3  里氏代换原则(L):父类出现的地方子类也可以,也就是子类可以替换父类而且使得程序可以正常运行。

4  接口隔离原则(I):接口的设计应该保持单一功能,使用多个单一功能的接口比使用一个总接口要好。

5  依赖倒转原则(d):抽象不应该依赖于细节(实现类),细节应该依赖于抽象。高层模板不应该依赖于低层模块,应该依赖于抽象。

6  迪米特原则原则(最少知道原则):一个类对另外一个类应该了解越少越好,高内聚,低耦合。

回归上面提到的,我们是前端工程师,这后面四种作为了解内容,但是前面俩种必须知道,这是我们的重点内容。

单一职责和开发封闭是我们应该需要掌握的内容,回想一下自己以前写的代码是否符合这俩个准则。

举一个简单的例子来熟悉一下这俩个准则。


function loadImg(src) {return new Promise((resolve, reject) => {const img = document.createElement("img");img.src = src;img.onload = function () {resolve(img);}img.onerror = function () {reject("图片加载错误!")}})
}let src = "http://img0.imgtn.bdimg.com/it/u=276772730,3789231562&fm=26&gp=0.jpg";
const result = loadImg(src);
result.then((img) => {console.log(`${img.width}`)return img;
}).then((img) => {console.log(`${img.height}`)return img
}).catch((err) => {console.log(err);
})

这是一个使用promise来加载图片的例子。

这个例子里面我使用了俩个then第一个then里面打印的是img.width  第二个then里面是打印img.height。虽然看起来是很傻的俩个操作,但是我想强调的是,每一个then就相当于一个程序段,里面只需要完成自己单一的任务,当增加其他功能时,我们不需要修改上面的俩个then,再添加一个then即可。

假如我们要进行的操作是否复杂,而且十分庞大,全部都放在一个程序段里面完成,那么在后期维护上面就十分的复杂了。上面的例子也许不是很恰当,但是能够表示出意思。

单一职责和开放封闭是我们学习的重点法则。

接下来 我们看俩道题目,来帮助大家理解面向对象设计原则。

大家觉得这题目如何,假如需要你设计你该如何设计了?思考一下,然后在继续看下面内容。

首先,我们可以知道任何车都有车牌号和名称,也就是说我们可以抽象一个车作为父类,包含车牌号和名称。因为价格,快车和专车不一样,我们可以把价格属性放到子类(快车和专车)中。

大家现在想一下,行程和是什么车有关系吗?快车有行程,专车也有行程,即行程应该和父类关联起来,而不是子类。最后一点,打车金额是行程的还是车的?  很明显应该是行程的。

画出UML图

写出JS代码

class Car {constructor(name, number) {this.name = name;this.number= number;}
}class KuaiChe extends Car {constructor(name, number) {super(name, number);this.price = 1;}
}
class ZhuanChe extends Car {constructor(name, number) {super(name, number);this.price = 2;}
}
class Trip {constructor(c) {this.car = c;}start() {console.log(`${this.car.name}车为你服务,车牌号为${this.car.number}`)}end() {console.log(`你需要支付${this.car.price * 5}元`)}
}const c = new KuaiChe("奔驰", 100);
const t = new Trip(c);
t.start();
t.end();

下面题目会有难度

这道题目相较于上面一道题目难度提升很大。

从第一句话就应该了解到,我们需要建立停车场类(park) 层类(floor) 停车位类(place)

第二句话,我可以得到每个车位应该有俩个方法(in out)来表示车的驶入和离开,还应该在停车位类上面设置一个标志位isEmpty表示是否是空的。

第三句话:我们应该知道停车场里面有一个方法用于计算机每一层的空位,那么计算每一层的空位应该谁来做比较好?很明显应该是floor类来做。

第四句话:我们应该知道还需要一个摄像头类,当车辆进入后,用来记录车牌号和时间,记录的值应该保存在停车场里面。

第五句话:我们应该需要一个显示器类,当车辆出来时,显示车牌号和停车时长。

UML类图如下:

我们用代码实现一下

class Car { //车类constructor(number) {this.number = number; //车牌号}
}class Camera {//照相机类constructor() {};shot(car) { return {number: car.number,cTime: Date.now()}}
}
class Screen { //显示器constructor() {};show(obj) {console.log(`车牌号${obj.number}准备离开,停车时间${Date.now()-obj.cTime}`)}
}class Place { // 车位constructor() {this.isEmpty = true;}in() { //有车进入this.isEmpty = false;}out() { //有车出去this.isEmpty = true;}
}class Floor { // 层类constructor(index, places) {this.index = index;this.places = places;}calEmptyPlace() { //计算每一层空位let cnt = 0;this.places.forEach((item) => {if (item.isEmpty) cnt++;})return cnt;}
}
class Park { //停车场constructor(floors) {this.floors = floors;this.camera = new Camera();this.screen = new Screen();this.car = {};}calEmpty() {this.floors.forEach((item) => {console.log(`第${item.index}层的空位是${item.calEmptyPlace()}个\n`)})}in(car) {this.calEmpty(); //显示有多少车辆const info = this.camera.shot(car); //拍照//停在那里 这个由车主自己决定const index = 0; //假设第一层const pot = parseInt((Math.random() * 100) % 100);const place = this.floors[index].places[pot]; //取车位place.in(); //进入this.car[info.number] = {info,place}//保存拍照信息}out(car) {this.screen.show(this.car[car.number].info); //显示this.car[car.number].place.out();}
}const floors = [];
for (let i=0; i<3; i++) {let places = [];for (let j=1; j<=100; j++) {places[j] = new Place();}floors[i] = new Floor(i+1, places);
}const p = new Park(floors);const car1 = new Car(1);
const car2 = new Car(2);
const car3 = new Car(3);console.log("第一辆车来了")
p.in(car1);
console.log("第二辆车来了")
p.in(car2);
console.log("第一辆车走了")
p.out(car1);
console.log("第二辆车走了")
p.out(car2);
console.log("第三辆车来了")
p.in(car3);
console.log("第三辆车走了")
p.out(car3);

看一下效果如何

预期效果一样。

推荐大家自己动手实现,自己写出来了,才学会了。

大家可以看左边个人分类的目录,跟着一起学习。

JavaScript -- 设计模式 设计原则相关推荐

  1. 设计模式-设计原则(Design Principle)

    本文由@呆代待殆原创,转载请注明出处. 写在前面:所谓设计原则并不是一定要遵守的法则,只是一种建议,因为保持这些原则本身会有一定代价,若是这些代价超过了带来的好处就得不偿失了,所以一切还是以简单为准. ...

  2. 设计模式——设计原则

    设计模式--六种设计原则 1. 开闭原则:对扩展开放,对修改闭合 对扩展开放:有新的需求或变化时,通过现有代码进行扩展,来适应新的情况 对修改闭合:设计一旦完成,就可以独立完成工作,不对已有的代码进行 ...

  3. 模块递归拆分法: 设计模式 设计原则,复杂层次设计举例。系统重构 装饰模式,门面模式,代理模式

    程序员最牛逼的能力是模块拆分能力, 然后才能利用模块依赖的工具,java 9 或者 runtime期的osgi ,其他maven插件,maven build期. 其他idea插件,类似阿里云的代码规范 ...

  4. 设计模式-设计原则之里氏代换原则

    设计原则之里氏代换原则 里氏代换原则 案例(正方形不是长方形) 案例改进 里氏代换原则 里氏代换原则是面向对象设计的基本原则之一. 里氏代换原则:任何基类可以出现的地方,子类一定可以出现. 通俗理解: ...

  5. JAVA设计模式-设计原则(三)里氏代换原则

    1.概念  任何基类可以出现的地方,子类一定可以出现. 子类对象 能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏. 2.为什么使用里氏替换原则 继承优点:     ...

  6. 设计模式-设计原则-开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段...

    开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段,它们相辅相成,相互补充,目标一致,只是分析问题时所站角度不同而已. 转载于:https://www.cnblogs.com/jiangtao12 ...

  7. 设计模式-设计原则之迪米特原则

    例子 假设老板给项目组长下达一个任务,让其去查询课程的数量 代码 public class Course {} public class TeamLeader {public void checkNu ...

  8. .NET 云原生架构师训练营(设计原则设计模式)--学习笔记

    ▲ 点击上方"DotNet NB"关注公众号 回复"1"获取开发者路线图 学习分享 丨作者 / 郑 子 铭 这是DotNet NB 公众号的第180篇原创文章 ...

  9. javascript设计模式_JavaScript 设计模式 学习总结

    ---------------------------------------------------------------------------------------------------- ...

最新文章

  1. mybatis常用标签和动态查询
  2. jsp点击按钮弹出输入框_按键精灵UI界面的输入框原来是这样使用的
  3. 十分钟了解分布式计算:Petuum
  4. 深入浅出设计模式原则之迪米特法则(LoD)
  5. oracle数据库安装自动化,自动化Oracle数据库静默安装
  6. Pc-98 android,PC安卓多功能搞机助手3.98
  7. flutter 生成文档_flutter 如何实现文件读写(使用篇)
  8. 《天天数学》连载20:一月二十日
  9. JS等比例缩小图片尺寸
  10. Windows 7 SP1 旗舰版 MSDN原版
  11. java 限制文件大小_java上传文件大小限制
  12. 如何通过a链接实现图片下载
  13. 软件测试 | App测试——Appium实战总结,淘宝App测试项目案例
  14. 同步练习(Java SE(九))补充
  15. 解决:RSA host key for [ip] has changed and you have requested strict checking.
  16. 分享30个优秀的网站导航设计案例
  17. invalid byte 1 of 1-byte UTF-8 sequence
  18. 好莱坞明星识别-第六周
  19. 电磁场与仿真软件(22)
  20. 主成分分析和主成分回归

热门文章

  1. 安装包安装失败,返回代码res=-113
  2. 个人做自媒体怎么运营?
  3. java字符串替换最后一个字符,详细解说
  4. 色深 抖动 色域 色准
  5. 华为云网站安全如何保障企业安稳运行?
  6. 小松鼠是一只很可怜的动物(原创)
  7. GT911电容触摸屏使用
  8. 软件驱动创新,戴尔科技打造现代化存储体验
  9. 蓝桥 墓地雕塑 JAVA
  10. 飞信免费消息api,飞信接口