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());
}
}
学习设计模式会很快的提升自己思维。以上就是今天的全部内容了,很快更新其他三个原则啦!!!



