[好程序员训练营]-----java基础笔记之设计模式之单例模式和工厂模式

时间:2021-12-28 12:39:08

<A href="http://www.goodprogrammer.org/" target="blank">android培训</a>------我的java笔记,期待与您交流!

前两天刚了解java的设计模式,学习了几种常见的设计模式,,今天就简单的把我的做个总结吧!

废话不多说开始做笔记

一,什么是设计模式呢?使用设计模式有什么好处呢?

首先要说一下设计模式不是一种开发语言也不是一组好规则,而是一种设计思想,是一种前人经验的总结而成的设计思想.

我查阅百度百科中说明如下:设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

二,java的设计模式有23种分别划分为3大类:

分别是创建设计模式(6种),结构设计模式(7种),行为模式(10种),这里实在太多,而且基础阶段也用不了太多,就知道常见的几种就行了,所以不再去说了

三,面向对象编程的设计原则

1,单一职责原则:它的核心思想就是我们常说的"高内聚,低耦合";

我的理解是我们在实际编程中,我们写的每一个类,都应该有唯一的职责,每一个方法中也都要有唯一的职责,不要一个类中需不需要的行为都有,不要用一个方法中实现所有的功

比如我们有一个猫和狗的类,猫的类中有eat()吃鱼这个方法,狗的类中有lookHome()这个看门的方法,那描述猫的类中猫的属性可以有姓名,年龄,爱好等等,你用到什么属性就去添加来描述它,用不到的不要多写一个,同理你如果想描述猫吃鱼的行为就定义一个eat()方法,那么就把猫吃鱼的代码给封装到eat()中,但是像猫的其他行为如果需要描述的话就要将这些描述行为的代码封装到另外一个方法中,而不是都放在eat()中,如果你需要一个狗的看门的方法那么就要定义一个狗的类来将狗看门的行为的代码抽取封装到狗这个类中的lookHome()方法中,而不是将lookHome()定义在猫的类中或者将lookHome()的代码封装在eat()中,不然势必造成代码结构不清晰,混乱,更不利于后期代码的扩展和维护.


2,开闭原则:它的核心思想就是一个对象对外扩展开放,对内关闭修改

我的理解是对类的改动是通过增加代码来实现的,而不是通过改动现有的代码来实现的.我们在编程中遇到一些容易以后改动的部分,就借助于抽象和多态给他向上抽取出来,而具体的实现让子类通过继承或者实现接口来处理它,比如我现在写了一个描述手机的类,具有的功能是打电话call()的功能,但是我现在由于需要,必须添加一个发短信的功能,如果我现在在手机类中添加senMessage()这个发短信的功能,那么以后每一次需求就要破坏手机这个类的代码结构,而且很不方便,现在我把打电话这个基本功能给他向上抽取成抽象方法,那么此类也必须成为抽象类,现在再有需求我就直接继承这个抽象类,添加的功能在他的子类中就行了,这样原先的代码就不用改动了,全部交给子类去处理,后期维护要添加什么功能全部新创建子类去继承或者实现父接口就行了,不用改动父类的代码,但是不好的提防我认为是增加了很多不必要的代码,这是权衡之下拿代码量来换方便


3,里氏替换原则:它的核心思想就是在任何出现父类的地方都可以用他的子类代替

其实就是同一个继承体系中,应该有共同的行为特征,父类具有最基本的特征,子类扩展父类的功能,当然子类肯定也有父类的基本特征


4,依赖注入原则,据说是学了JavaEE的Spring框架后会有深刻的理解,我没有学习就写些简单的个人理解吧

它的核心思想就是要依赖于抽象来编程不是依赖于具体的类来编程,如果依赖于具体的类来编程以后需要扩展功能会很麻烦,依赖于抽象的类或者接口倒是很方便的后期的功能扩展,所以我们常说要面向接口编程,而不是面向具体的类来编程.


5,接口分离原则:核心思想就是不应该强迫程序依赖他们不需要使用的方法

就是说一个接口不应该有太多的行为,一个接口只提供一种对外访问的功能,而不是把所有的功能都封装在一个接口中.

6,迪米特原则:一个对象应该对其他的对象尽可能少的了解

其实就是说降低各个对象之间的耦合性,系统的各个模块之间使用接口进行编程,而不要去理会内部的结构,和工作原理,这样便于系统后期的维护.


四:简述工厂设计模式

其实工厂设计模式不是一种一般有三种:第一个是简单工厂设计模式也叫静态工厂设计模式,特点是定义一个具体的工厂类负责创建一些类的实例,工厂中的方法都是静态的,

比如我们现在造一个Animail接口,接口中的抽象方法是public abstract void eat();用来描述动物的吃的行为,现在我们定义2个具体的类,猫类和狗类分别implements Animail类,实现其中的eat(),现在我们再写一个工厂类StaticFactory,该类定义了2个静态方法,public static Dog  newDog(){return new dog;}  和public static Cat newCat(){return new Cat;};

那我们就可以在客户端的测试类AnimailTest中直接根据类名来调用StaticFactory来调用其中的静态方法从而创建猫和狗的对象.    但是我们现在要是想再创建兔子对象,我们不仅要在写一个兔子类实现Animail,h还要在StaticFactory这个工厂类中添加产生兔子对象的工厂方法,所以很麻烦不利于后期维护

静态工厂设计模式的优点是:客户端不用再负责创建对象的工作,明确了各个类的职责.

缺点是:如果后期需要创建新的对象那么就需要不断的修改已有的这个具体的工厂类,不利于维护.


第二种是工厂方法模式,它弥补了静态工厂模式的缺点,它的特点是定义一个工厂接口来负责各个具体类对象的具体工厂类,具体类的对象的创建由实现该接口的具体工厂类来负责创建

我们还是以猫狗为例,定义一个Animail接口,描述动物的eat(),定义一个大的工厂接口Factory,再分别定义具体的猫类和狗类,再分别定义产生猫和狗的工厂类CreatCat和CreatDog类来实现大的工厂类Factory,覆写里面的creatAnimail()方法,这样就达到了客户端轻松创建猫和狗对象的目的,如果后期要创建兔子的实例,那我们只需要定义一个具体的描述兔子的类,然后定义一个具体的创建兔子对象的类来实现大的工厂类Factory,实现其中的creatAnimail()方法即可,

它的优点是:客户端不需要再负责对象的创建,如果后期需要创建别的对象,只需要增加一个具体的类和这个类对应的工厂即可,不需要改写已有的代码

缺点是:增加了代码量.

第三种是抽象工厂模式,由于现在还用的不多,我在这里就不多说了,以后用到再来补上


五:单例模式浅说

来说单例设计模式之前我们先来说几个问题

何谓单例设计模式?单例模式就是某一个类在内存中必须只有一个对象,

那么如何保证对象唯一呢,

我们就把该类的构造方法给他私有化即private,所以别的类中便不可以创建它的对象,

但是问题又来了,我们不能创建该类的对象,那么这个类存在还有太大的意义吗?

所以我们必须要拿到那个对象以便我们使用.那么我们怎么拿到这个对象呢?

其实很简单,我们只需要在该类中对外提供一个方法,该方法中返回该对象就行了


单例模式分为饿汉式和懒汉式,下面来看一下饿汉式代码体现:

class SingleA{

private SingleA(){

}

private  static SingleA  s = new SingleA();

public static SingleA getSingle(){

rerurn s;

}

}

我们来看一下懒汉式的代码体现:

class SingleB{

private static SingleB s=null; 

private SingleB(){

}

public static SingleB getSingle(){

if(s==null)

s=new SingleB();

return s ;

}

}

那我们来看一下懒汉式和饿汉式有什么区别呢?

饿汉式是上来就造对象不管这个对象是不是要被使用.只要这个类一加载就造对象,而懒汉式的话即使类被加载也不会去创建这个唯一的对象,因为开始引用为null,只有等到第一次使用的时候才回去创建它,其实这里就是个懒加载思想.

还有一个区别是饿汉时在开发中会比较常用,因为他是安全的,但是懒汉式不是线程安全的,但是我们可以在该方法上加上synchronized关键字从而来解决线程安全问题