其他
JS面向对象之 7 大基本原则
单一职责
类的复杂性降低,实现什么职责都有清晰明确的定义 可读性提高,复杂性降低,那当然可读性提高了 可维护性提高,可读性提高,那当然更容易维护了 变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。
constructor(){
this.goods = [];
}
addGoods(good){
this.goods = [good];
}
getGoodsList(){
return this.goods;
}
}
class Settlement {
constructor(){
this.result = 0;
}
calculatePrice(list,key){
let allPrice = 0;
list.forEach((el) => {
allPrice += el[key];
})
this.result = allPrice;
}
getAllPrice(){
return this.result;
}
}
开闭原则
把其中依赖的代码copy一份到新的类中。 在新类中引用旧类中的方法。
开闭原则有利于进行单元测试 开闭原则可以提高复用性 开闭原则可以提高可维护性 面向对象开发的要求
down(){
// ...
}
move(){
// ...
// 对拖拽没有做任何限制可以随意拖拽
}
up(){
// ...
}
}
class LimitDrag extends Drag {
move(){
// ...
// 重写该方法对拖拽进行限制处理
}
}
里氏替换
代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性 提高代码的重用性 子类可以形似父类,但是又异于父类。 提高代码的可扩展性,实现父类的方法就可以了。许多开源框架的扩展接口都是通过继承父类来完成。 提高产品或项目的开放性
class AbstractGun {
shoot(){
throw "Abstract methods cannot be called";
}
}
// 步枪
class Rifle extends AbstractGun {
shoot(){
console.log("步枪射击...");
}
}
// 狙击枪
class AUG extends Rifle {
zoomOut(){
console.log("通过放大镜观察");
}
shoot(){
console.log("AUG射击...");
}
}
// 士兵
class Soldier {
constructor(){
this.gun = null;
}
setGun(gun){
this.gun = gun;
}
killEnemy(){
if(!this.gun){
throw "需要给我一把枪";
return;
}
console.log("士兵开始射击...");
this.gun.shoot();
}
}
// 狙击手
class Snipper extends Soldier {
killEnemy(aug){
if(!this.gun){
throw "需要给我一把枪";
return;
}
this.gun.zoomOut();
this.gun.shoot();
}
}
let soldier = new Soldier();
soldier.setGun(new Rifle());
soldier.killEnemy();
let snipper = new Snipper();
// 分配狙击枪
snipper.setGun(new AUG());
snipper.killEnemy();
snipper.setGun(new Rifle());
// snipper.killEnemy(); // this.gun.zoomOut is not a function
依赖倒置
高层模块不应该依赖低层模块,两者都应该依赖其抽象 抽象不应该依赖细节 细节应该依赖抽象
通过依赖于接口,隔离了具体实现类 低一层的变动并不会导致高一层的变动 提高了代码的容错性、扩展性和易于维护
class AbstractGun {
shoot(){
throw "Abstract methods cannot be called";
}
}
// 步枪
class Rifle extends AbstractGun {
shoot(){
console.log("步枪射击...");
}
}
// 狙击枪
class AUG extends AbstractGun {
shoot(){
console.log("AUG射击...");
}
}
接口隔离
避免接口污染 提高灵活性 提供定制服务 实现高内聚
class Mix {}
for (let mixin of mixins) {
copyProperties(Mix, mixin);
copyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if ( key !== "constructor"&& key !== "prototype"&& key !== "name") {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
class Behavior {
eat(){
throw "Abstract methods cannot be used";
}
call(){
throw "Abstract methods cannot be used";
}
}
class Action {
climbTree(){
throw "Abstract methods cannot be used";
}
}
class Dog extends Behavior{
eat(food){
console.log(`狗正在吃${food}`);
}
hungry(){
console.log("汪汪汪,我饿了")
}
}
const CatMin = mix(Behavior,Action);
class Cat extends CatMin{
eat(food){
console.log(`猫正在吃${food}`);
}
hungry(){
console.log("喵喵喵,我饿了")
}
climbTree(){
console.log("爬树很开心哦~")
}
}
let dog = new Dog();
dog.eat("骨头");
dog.hungry();
let cat = new Cat();
cat.eat("鱼");
cat.hungry();
cat.climbTree();
迪米特法则
减少对象之间的耦合性
close(){
throw "Abstract methods cannot be used";
}
}
class System extends ISystem{
saveCurrentTask(){
console.log("saveCurrentTask")
}
closeService(){
console.log("closeService")
}
closeScreen(){
console.log("closeScreen")
}
closePower(){
console.log("closePower")
}
close(){
this.saveCurrentTask();
this.closeService();
this.closeScreen();
this.closePower();
}
}
class IContainer{
sendCloseCommand(){
throw "Abstract methods cannot be used";
}
}
class Container extends IContainer{
constructor(){
super()
this.system = new System();
}
sendCloseCommand(){
this.system.close();
}
}
class Person extends IContainer{
constructor(){
super();
this.container = new Container();
}
clickCloseButton(){
this.container.sendCloseCommand();
}
}
let person = new Person();
person.clickCloseButton();
01组合/聚合复用原则
新的实现较为容易,因为超类的大部分功能可通过继承关系自动进入子类; 修改或扩展继承而来的实现较为容易。
class Mix {}
for (let mixin of mixins) {
copyProperties(Mix, mixin);
copyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if ( key !== "constructor"&& key !== "prototype"&& key !== "name") {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
class Savings {
saveMoney(){
console.log("存钱");
}
withdrawMoney(){
console.log("取钱");
}
}
class Credit {
overdraft(){
console.log("透支")
}
}
const CarMin = mix(Savings,Credit);
class UserCar extends CarMin {
constructor(num,carUserName){
super();
console.log()
this.carNum = num;
this.carUserName = carUserName;
}
getCarNum(){
return this.carNum;
}
getCarUserName(){
return this.carUserName;
}
}
let myCar = new UserCar(123456798,"Aaron");
console.log(myCar.getCarNum());
console.log(myCar.getCarUserName());
myCar.saveMoney();
myCar.withdrawMoney();
myCar.overdraft();
总结
作者:Aaron
https://segmentfault.com/a/1190000020319171- ------- end -------- -
❤️ 看完两件事
如果你觉得这篇内容对你有所帮助,我想邀请你帮我两个小忙:
点个「
在看
」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)关注公众号「IT平头哥联盟」,一起进步,一起成长!
推荐阅读: