Hello,各位,好久没发布内容了,现在转做Java语言,目前基础已经学习一大半,正在钻研设计模式,第一天开始学习,废话不多说,走起!!!
我个人比较喜欢先概念再实战,这样可以提高自己在敲代码中的思维能力,所以这些概念都是以自己的理解(非官方),我认为只有自己理解才是自己的!!!
+一.开闭原则+
----1.1意义----
对扩展开放,对修改关闭,意思就是在程序需要更新的时候进行扩展,而不是修改自身大多数代码,易于维护与更新。
相信刚和我一样接触设计模式的小伙伴,写项目的时候很少会动用抽象与接口,这样会在项目更新一个新功能的时候修改很多细节代码,甚至其他的类也要修改,这样的会大大提高开发时间与代码复杂性。
所以我们可以这样,设计项目的时候先想象该怎么设计,根据需求设计抽象类或者接口,然后具体实现就交给它们的子类即可。修改时就可以再不动用原来的代码情况下,只需修改子类。弱话耦合性,增强多态性。抽象合理,保持代码整体结构的稳定,容易变化的细节就交给子类去实现
我理解的一句话:需求决定抽象(想象的),抽象决定子类(具体类)
------下面举个实际例子------
----1.2实战----
目前还不会用自带的UML插入索性画了一张,有点丑,不要建议
这里拿搜狗输入法举例,输入法是有背景皮肤的,但是我们可以自己调换皮肤。那我们可以根据需求先设计一个皮肤的抽象类,然后在定义默认皮肤类和一个花皮肤类继承于抽象皮肤类,实现多态。之后在将抽象类作为他的成员变量(图中的依赖关系),这样做的好处是我可以赋值给他各种各样他的子类,从而又能实现多态并且减少耦合,以后想用其他的皮肤,我就可以再定义一个皮肤的子类即可,又不用改sougou类的。
----1.3献上代码----
//抽象皮肤类 public abstract class AbstractSkin { public abstract void showName();//显示皮肤 } //默认皮肤类 public class DefaultSkin extends AbstractSkin{ //重写显示皮肤方法 public void showName(){ System.out.println("已切换成默认皮肤"); } } //花皮肤类 public class FlowerSkin extends AbstractSkin{ //重写显示皮肤方法 public void showName(){ System.out.println("已切换成花皮肤"); } } //搜狗输入法类 public class SougouInput { AbstractSkin skin; //构造方法 public SougouInput() { this.skin = new DefaultSkin();//这里我先设置它为默认皮肤 this.skin.showName(); } //设置皮肤 public void setSkin(AbstractSkin skin) { this.skin = skin; this.skin.showName();//打印显示皮肤 } } //测试类 public class Test { public static void main(String[] args) { //创建一个实例 SougouInput sougou = new SougouInput();//在构造方法中设置默认皮肤 //创建一个花皮肤对象 AbstractSkin flower = new FlowerSkin(); //设置花皮肤 sougou.setSkin(flower); } }
以上就是关闭原则的全部内容,请看下面的里氏换原则
+二.里氏代换原则+
原则:任何基类可以出现的地方,子类一定可以出现
通俗点讲就是子类可以扩展父类的方法,但是不能改变父类原有的功能。换句话说,子类继承父类时,可以添加功能,但尽量不要重写父类的方法,因为可能会导致整个体系的复用性变差
注:如果必须重写的话,可以将其定义为抽象
这个很容易理解,可以在以后的实战例子中慢慢去体会,来下面给大家带来今天的第三个原则,注意!!!这个原则我感觉很重要!!!
+三.依赖颠倒原则+
----3.1意义----
顾名思义是说上级和下级不要颠倒,什么意思呢?高层模块不应该依赖低层模块(被关联的类作为低层,关联的类作为高层,关联的类中有被关联的类作为成员对象)。两者都应该依赖于抽象,抽象不应该依赖于细节(具体实现),细节(具体实现)依赖于抽象。
简单来说在以后的项目开发中是面向抽象而不是面向细节(具体实现)。先抽象,后具体!!!
----3.2实战----
3.2.1拿一个电脑举例子
一台电脑需要CPU,内存条,硬盘。只有拥有这些,一台电脑才能正常运行。可CPU有很多种可以有英特尔,ATM…硬盘:希捷,西部数据…内存条:影驰,英睿达…
UML图如下(注意:图中的Computer类方法太多不够画的就不详细写,具体代码区见):
电脑需要这些配件,没有就运行不起来,所以是组合关系。在这里组合的全是配件的抽象类,需要用其他的样式的配件,只需在该配件的抽象类下在写一个具体类即可。
//CPU抽象接口 public interface Cpu { void run();//运行 } //英特尔CPU public class InterCpu implements Cpu{ //重写运行函数 public void run(){ System.out.println("英特尔Cpu开始运行"); } } //硬盘抽象接口 public interface HardDisk { void save(String data);//保存数据 String get();//获取数据 } //希捷硬盘 public class XijieHardDisk implements HardDisk{ private String data; public XijieHardDisk() { this.data = null;//默认设置保存为null } //保存数据 public void save(String data){ this.data =data; System.out.println("数据保存成功!!!"); } //获取数据 public String get(){ return this.data; } } //内存条抽象接口 public interface Memory { void save();//存储 } //影驰内存条 public class YinchiMemory implements Memory{ //重写save类 public void save(){ System.out.println("影驰内存条已开始使用"); } } //电脑 public class Computer { Cpu cpu;//CPU HardDisk hard;//硬盘 Memory memory;//内存条 public Computer(Cpu cpu, HardDisk hard, Memory memory) { this.cpu = cpu; this.cpu.run();//因为内电脑创建好了CPU就可以动了,所以在这里直接调用run() this.hard = hard; this.memory = memory; this.memory.save();//因为内电脑创建好了内存条就可以动了,所以在这里直接调用save() } public Cpu getCpu() { return this.cpu; } public HardDisk getHard() { return this.hard; } public Memory getMemory() { return this.memory; } public void setCpu(Cpu cpu) { this.cpu = cpu; } public void setHard(HardDisk hard) { this.hard = hard; } public void setMemory(Memory memory) { this.memory = memory; } } //测试类 public class Test { public static void main(String[] args) { //创建一个英特尔CPU Cpu cpu = new InterCpu() ; //创建一个希捷硬盘 HardDisk hardDisk = new XijieHardDisk(); //创建一个影驰内存条 Memory memory = new YinchiMemory(); //创建一台电脑 Computer computer = new Computer(cpu,hardDisk,memory); //硬盘存储数据 computer.getHard().save("HelloWorld"); //打印硬盘中的数据 System.out.println("硬盘中的数据为"+computer.getHard().get()); } }
学习设计模式会很快的提升自己思维。以上就是今天的全部内容了,很快更新其他三个原则啦!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)