博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向对象七大基本原则
阅读量:5166 次
发布时间:2019-06-13

本文共 5401 字,大约阅读时间需要 18 分钟。

案例需求: 一个人想买一个电脑。

简单实现:

class User {    getComputer () {        console.log('跑很远去买220v电源'),//表达的是这个过程很复杂,        console.log('跑很远买16存显示器')        //。。。。。        console.log('组装');    }};new User().getComputer();

上面的实现满足了我的需求。但是有个问题:在getComputer方法中,每次都要跑很远去买,然后自己组装,整个过程繁琐复杂(脑补getComputer方法内部的代码很长很长)。如果能有人送货,就好了。

解决思路就是单一原则: 一个类或方法只做一件事。

class User {    dianyuan(num) {        console.log(`买了个${num}v电源`)    }    screen(num) {        console.log(`买了个${num}寸显示器`)    }    zz() {       console.log('组装')     }    getComputer () {        this.dianyuan(220);        this.screen(20);                //。。。。。        this.zz();    }};new User().getComputer();

 在新实现中,我随便打几个电话(将不同类型的零件单独定义为各自的函数,调用dianyuan/screen...,实现单一原则),就能得到想要类型的零件。但是,不是每个人都像我这样了解电脑零件及组装过程的,对于小白来说,它希望有个经销商能直接帮他完成零件购买及组装的过程,

解决思路:再次使用单一原则

 

class Computer {    dianyuan() {        console.log(`买了个200v电源`)    }    screen(num) {        console.log(`买了个17寸显示器`)    }    all() {        this.dianyuan();        this.screen();    }}class User {        zz() {       console.log('组装')     }    getComputer () {        let computer = new Computer(220, 20);        computer.all();        this.zz();    }};new User().getComputer();

  

  这次实现中, 我将获取零件的过程封装成了一个类,它能返回组装一个电脑所需要的所有零件;从此小白获取一个电脑的方法就是调用以下Computer.all()方法。但是只有一个经销商实在是太被动了,我不能货比三家,我希望所有的经销商都具备获取所有零件的能力,但是各自零件的类型及价钱又能让我可以选择。

解决思路:

1抽象:抽取事物的本质,剔除具体表现。

2里氏替换:子类能够出现在所有父类出现的地方。

3依赖倒置:程序应该依赖抽象接口, 而不依赖具体实现。

class SuperComputer {    dianyuan() {    }    screen() {    }    all() {        this.dianyuan();        this.screen();    }}class SubOneComputer extends SuperComputer{    dianyuan() {        console.log('我们家的220电源10元')    }    screen() {        console.log('我们家17屏幕20元');    }}class SubTwoComputer extends SuperComputer {    dianyuan() {        console.log('我们家的220电源20元')    }    screen() {        console.log('我们家17屏幕10元');    }}class User {        zz() {       console.log('组装')     }    getComputer (computer) {        //为了程序的健壮性, 你需要判断这个参数是否是某经销商的实例(能够调用all()),从而产生某个经销商的依赖, 然后最好的实现方式就是判断它是否是某个抽象类的实例,避免对扩展子类的依赖, 这就是依赖倒置原则        if (computer instanceof SuperComputer) {            computer.all();            this.zz();        } else {            console.log('请传入经销商的实例')        }    }};let  xiaoming= new User();xiaoming.getComputer(new SubOneComputer());let xiaohong = new User()xioahong.getComputer(new SubTwoComputer());

  小红/小明通过不同经销商那拿到不同类型的零件,但是零件肯定是齐全的,这得力于两点。

1:抽象类SuperComputer为所有的经销商定义了标准(是不是有点抽象接口的概念)。

2:经销商实现了SuperComputer定义的所有零件方法。这就是里氏替换带来的好处。

3:为了User.getComputer()的健壮性, 你需要判断computer是否是某经销商的实例(能够调用all()),从而产生某个经销商的依赖, 然后最好的实现方式就是判断它是否是某个抽象类的实例,从而避免对扩展子类的依赖,毕竟抽象类的最可靠。

然后 而不然后经销商又了新的问题, 为了盈利,他必须扩大业务范围。

解决思路:

开闭原则:对修改关闭, 对扩展开放

 

class SuperComputer {    dianyuan() {    }    screen() {    }    all() {        this.dianyuan();        this.screen();    }}class SubOneComputer extends SuperComputer{    dianyuan() {        console.log('我们家的220电源10元')    }    screen() {        console.log('我们家17屏幕20元');    }    paper() {        console.log('A4纸1毛一张')    }}class SubTwoComputer extends SuperComputer {    dianyuan() {        console.log('我们家的220电源20元')    }    screen() {        console.log('我们家17屏幕10元');    }    netline() {        console.log('网线1米2元')    }}class User {        zz() {       console.log('组装')     }    getComputer (computer) {        //为了程序的健壮性, 你需要判断这个参数是否是某经销商的实例(能够调用all()),从而产生某个经销商的依赖, 然后最好的实现方式就是判断它是否是某个抽象类的实例,避免对扩展子类的依赖, 这就是依赖倒置原则        if (computer instanceof SuperComputer) {            computer.all();            this.zz();        } else {            console.log('请传入经销商的实例')        }    }};let  xiaoming= new User();xiaoming.getComputer(new SubOneComputer());let xiaohong = new User()xioahong.getComputer(new SubTwoComputer());

  上面的两个经销商为了利润, 各自扩大了经营范围(paper(), netline()),他们是对SupterComputer的扩展,而不能为单独的经销商在SuperComputer类中去添加跟电脑零件无关的方法,保证抽象的单一性,稳定性。

还有一个问题, 现在所有的小白能轻松的从不同的经销商那里获取全部零件,但是还是要自己组装, 还不够方便,其实小白们只需要找到一个会组装的人,这个组装的人肯定对于电脑零件是非常熟悉的,小白们不在关心电脑零件问题,。

解决思路: 

迪米特法则:一个对象应该对其他对象保持最少的了解

class SuperComputer {    dianyuan() {    }    screen() {    }    all() {        this.dianyuan();        this.screen();    }}class SubOneComputer extends SuperComputer{    dianyuan() {        console.log('我们家的220电源10元')    }    screen() {        console.log('我们家17屏幕20元');    }    paper() {        console.log('A4纸1毛一张')    }}class SubTwoComputer extends SuperComputer {    dianyuan() {        console.log('我们家的220电源20元')    }    screen() {        console.log('我们家17屏幕10元');    }    netline() {        console.log('网线1米2元')    }}//组装类class InitComputer {    software() {        console.log('安装软件')    }       hardware(computer) {        if (computer instanceof SuperComputer) {            computer.all();        } else {            console.log('请传入经销商的实例')        }    }    zz(money) {        switch(money)        {            case 5000:                 this.hardware(new SubOneComputer());//5000元的配置            case 4000:                this.hardware(new SubTwoComputer());//4000元的配置        }        this.software();        console.log('组装完毕');    }}class User {        getComputer (money) {        new InitComputer().zz(money);    }};let  xiaoming= new User();xiaoming.getComputer(4000);let xiaohong = new User()xioahong.getComputer(5000);

  终于搞定了,现在小白只需要给组装类money就能得到一台相应配置的电脑, 不用在找经销商及自己组装了。这就是迪米特法则, 小白不需要熟悉经销商的套路,而是通过组装类这个中间人去搞定。

以上的例子是我对公司培训面向对象6大基本原则的理解,总结以下:单一原则,开闭原则,里氏替换,抽象接口,依赖倒置,迪米特法则

转载于:https://www.cnblogs.com/pandapeter/p/10465068.html

你可能感兴趣的文章
解密Redis持久化
查看>>
Vue笔记:使用 axios 发送请求
查看>>
利用反射动态调用类成员
查看>>
富文本编辑器 - RichEditor
查看>>
angular学习(十五)——Provider
查看>>
机器学习在租房信息判别中的应用
查看>>
iOS crash 崩溃问题的追踪方法
查看>>
定制Android透明按钮
查看>>
prototype for '类名::函数名'does not match any in class'类名'
查看>>
如何让.NET Core应用的配置与源文件保持同步?
查看>>
南京Uber优步司机奖励政策(2月1日~2月7日)
查看>>
成都Uber优步司机奖励政策(3月25日)
查看>>
linux shell脚本获得当前文件路径
查看>>
团队作业9——第二次项目冲刺1(Beta阶段)
查看>>
LintCode刷题笔记-- Count1 binary
查看>>
java webcontroller访问时报415错误
查看>>
qcow2、raw、vmdk等镜像格式
查看>>
.NET:CLR via C# Assembly Loading
查看>>
wed开发基础--练习题
查看>>
【springBoot】之配置文件application
查看>>