Java面试 第 7 章 设计模式

设计模式(Design Pattern)是一套被反复使用、经过分类编目的、代码设计经验的总结。

使用设计模式的目的是为了代码重用,避免程序大量修改,同时使代码更易于理解,并且保证代码可靠性。

常见的设计模式有工厂模式(Factory Pattern)、单例模式(Singleton Pattern)、适配器模式(Adapter Pattern)、享元模式(Flyweight Pattern)以及观察者模式(Observer Pattern)等。


7.1 什么是单例模式

在某些情况下,有些对象只需要一个就可以了,即每个类只需要一个实例。简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。

单例模式确保某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例单例模式。单例模式只应在有真正的「单一实例」需求时才可使用。单例模式的设计类图如图 7-1 所示。

编码规范也明确指出应该要少用全局变量,因为过多使用全局变量,会造成代码难读;最后全局变量并不能实现继承(虽然单例模式在继承上也不能很好地处理,但是还是可以实现继承的)。而单例模式在类中保存了它的唯一实例——这个类,它可以保证只能创建一个实例,同时它还提供了一个访问该唯一实例的全局访问点。

使用单例模式,需要注意的是,单例模式用来保证系统中一个类只有一个实例。单例类的构造函数必须为私有,同时单例类必须提供一个全局访问点。

使用这种方法实现的单例模式,在类被加载时就会实例化这个类的一个对象,由于在使用之前对象已经创建好,因此,可以在多线程环境下使用这种方法。如果采用按需实例化的方法(在实例化对象在使用的时候才实例化),就需要考虑多线程的同步。


7.2 什么是工厂模式

工厂模式专门负责实例化有大量公共接口的类。工厂模式可以动态决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类。客户类和工厂类是分开的。消费者无论什么时候需要某种产品,需要做的只是向工厂提出请求即可。消费者无须修改就可以接纳新产品。当然也存在缺点,就是当产品修改时,工厂类也要做相应的修改。

工厂模式包含以下几种形态:

1)简单工厂(Simple Factory)模式。简单工厂模式的工厂类是根据提供给它的参数,返回的是几个可能产品中的一个类的实例,通常情况下,它返回的类都有一个公共的父类和公共的方法。简单工厂模式的设计类图如图 7-2 所示。

其中,Product 为待实例化类的基类,它可以有多个子类;Simple Factory 类中提供了实例化 Product 的方法,这个方法可以根据传入的参数动态地创建出某一类型产品的对象。

2)工厂方法(Factory Method)模式。工厂方法模式是类的创建模式,其用意是定义一个用于创建产品对象的工厂的接口,而将实际创建工作推迟到工厂接口的子类中。它属于简单工厂模式的进一步抽象和推广。多态的使用,使得工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。工厂方法模式的设计类图如图 7-3 所示。

Product 为产品的接口或基类,所有产品都实现这个接口或抽象类(例如 ConcreteProd-uct),这样就可以在运行时根据需求创建对应的产品类。Creator 实现了对产品的所有操作方法,而不实现产品对象的实例化。产品的实例化由 Creator 的子类来完成。

7.3 什么是适配器模式

适配器模式,它是把一个类的接口转换成客户端所期望的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够一起工作。适配类可以根据所传递的参数返还一个合适的实例给客户端。

适配器模式主要应用于「望复用一些现存的类,但是接口又与复用环境要求不一致」的情况,在遗留代码复用、类库迁移等方面非常有用。同时,适配器模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用「多继承」的实现方式,会引起程序的高耦合,所以一般不推荐使用;而对象适配器采用「对象组合」的方式,耦合度低,应用范围更广。

例如,现在系统里已经实现了点、线、正方形,而现在客户要求实现一个圆形,一般的做法是建立一个 Circle 类来继承以后的 Shape 类,然后去实现对应的 display、fill、undisplay 方法,此时如果发现项目组其他人已经实现了一个画圆的类,但是他的方法名却和自己的不一样(为 displayhh、fillhh、undisplayhh),则不能直接使用这个类,因为那样无法保证多态,而有的时候,也不能要求组件类改写方法名,在这样的情况下,可以采用适配器模式。适配器模式的设计类图如图 7-5 所示。

7.4 什么是观察者模式

观察者模式(也被称为发布/订阅模式)提供了避免组件之间紧密耦合的另一种方法,它将观察者和被观察的对象分离开来。在该模式中,一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关,结果是对象可以相互对话,而不必了解原因。Java 与 C#的事件处理机制就是采用的此种设计模式。

例如,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将它做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。观察者模式的设计类图如图 7-6 所示。

======================================

end 

发布了95 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_40993412/article/details/104033602
今日推荐