Java面试时常用设计模式的用途
一、Adapter模式
在软件版本升级的时候,以前版本的软件已经通过测试了,为了兼容老的版本,这时用Adapter
模式,可以轻松地同时维护新版本和老版本。实现方式:让新版本扮演Adaptee(被适配)角色,旧版
本扮演Target角色,接着编写一个扮演,Adapter角色的类,让它使用新版本的类来实现旧版本的类中
的方法。
二、Builder模式
Builder类的方法来编写文档,但是它并不知道它"真正"使用的哪个类。 正是因为不知道才
能替换,正是因为可以替换,组件才具有高价值。作为设计人员,我们必须时刻关注这种"可替换性"。
三、Chain模式
Chain of Responsibility模式的最大优点就在于弱化了发出请求的人(Client角色)和处理请
求的人(ConcreteHandler角色)之间的关系Client角色向第一个ConcreteHandler角色发出请
求,然后请求会在职责链中传播,直到某个ConcreteHandler角色处理该请求,使用Chain of
Responsibility模式,通过委托推卸责任,就可以根据情况变化动态地重组职责链。
如果固定写明"某个请求需要谁处理"这样的对应关系,那么很难在程序运行中去改变请求的处理者。
例如:在视窗系统中,用户有时需要可以自由地在视窗中添加控件
缺点:如果职责链太长,会导致处理请求发生了延迟
四、Composite模式
使用Composite模式可以使容器与内容具有一致性,也可以称其为多个和单个的一致性,即将多
个对象结合在一起,当作一个对象进行处理,递归结构那种,Entry类中定义了add方法,
所做的处理是抛出异常,这是因为能使用add方法的只能是Directory类。
五、Decorator模式
Decorator模式的主要目的是通过添加装饰物来增加对象的功能
用Decorator模式可以为程序添加许多功能。只要准备一些装饰边框(ConcreteDecorator角色),
即使这些装饰边框都只具有非常简单的功能,也可以将它们自由组合成为新的对象
java.io包与Decorator模式
Reader reader = new FileReader("datafile.txt"); ---读取文件
Reader reader = new BufferedReader(new FileReader("datafile.txt")); ---读取文件时将文件内容放入缓冲区
Reader reader = new LineNumberReader(new BufferedReader(new FileReader("datafile.txt"))); ---管理行号
缺点:Decorator模式的一个缺点是会导致程序中增加许多功能类似的很小的类
六、Facade模式
在大型系统中,类和方法很多,对于不是很熟悉业务的人来说,调用这些方法和类时就很麻烦。
不知道先使用哪个,后使用哪个,这时使用Facade模式就变得很有必要了。
从例子中看出:先从数据库中获取需要读取的配置文件,然后拿到用户名,然后html输出,
将这些步骤放到一个makeWelcomePage方法中,这样接口变少了,使用者也不用
担心这些方法和类的调用顺序和它们放在哪了。
在超大系统中,往往都含有非常多的类和包。如果我们在每个关键的地方都使用Facade模式,
那么系统的维护就会变得轻松很多
七、Factory模式
Factory模式:生成实例的工厂
父类决定市领导生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责,
这样就可以将生成实例的框架和实际负责生成实例的类解耦
使用设计模式设计类时,必须要向维护这些类的开发人员正确地传达设计这些设计模式的意图,
否则,维护人员在修改设计时可能会违背设计者最初的意图。
八、Flyweight模式
共享实例可减少内存使用,内存是资源的一种。时间也是一种资源,使用new关键字生成实例会花费时间。
通过Flyweight模式共享实例可以减少使用new关键字生成实例的次数。
这样就可以提高程序运行速度。
九、Iterator模式
1、为什么要引入Iterator模式,而不是直接用for循环遍历?
这样做主要是为了将遍历与实现分离开来,不管以后BookShelf后期放弃数组来管理书,都不
会影响到遍历,对于BookShelf的调用者来说真的太方便了。
2、设计模式的作用?
设计模式的作用就是帮助我们编写可复用的类,所谓"可复用",就是指将类实现为"组件",当一
个组件发生改变时,不需要对其他的组件进行修改或是只需要很小的修改即可应对。
3、为什么要用抽象类和接口
如果只使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再
次利用。为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,我们需要引入抽象类和接口
十、Mediator模式
主要是将需要集中处理的业务逻辑放到LoginFrame中,哪怕其中的某个需求改变了,并不会影响其它组件的使用。
面向对象编程可以帮助我们分散处理,避免处理过于集中。但是将一些业务处理分散在各个类中,
需求修改时不利于组件的复用。该分散时分散,该集中是集中。
十一、Memento模式
主要是用来保存实例的状态,在下次需要的时候进行复制。达到撤销,重做,历史记录,快照的效果
十二、observer模式
具体的观察者注册到subject,通过调用subject的execute方法,通知到观察者,执行每个观察者的方法
十三、Proxy模式
代理人只代理他能解决的问题。当遇到他不能解决的问题时,还是会"转交"给本人去解决。
十四、Singleton模式
将构造器私有化,将对象的创建作为成员变量私有化,提供静态方法出来获取对象
十五、State模式
在编程时,我们经常会使用分而治之的方针。它非常适用于大规模的复杂处理。当遇到庞大且复杂的
问题,不能用一般的方法解决时,我们会先将该问题分解为多个小问题。
分而治之:将一个复杂的大问题分解为多个小问题然后逐个解决
十六、Strategy模式
通常在编程时算法会被写在具体方法中。Strategy模式却特意将算法与其他部分分离开来,
只是定义了与算法相关的接口,然后在程序中以委托的方式来使用算法。
当我们想要通过改善算法来提高算法的处理速度时,如果使用了Strategy模式,就不必修改
Strategy角色的接口,仅仅修改ConcreteStrategy角色即可。使用委托这种弱关联关系可
以很方便的整体替换算法。
十七、Template Method模式
Template Method模式的优点:在父类的模板方法中编写了算法,因此无需在每个子类中再编写算法。
如果在使用Template Method模式进行编程,当我们在模板方法中发现Bug时,只需要修改模
板方法即可解决问题。
类类对子类的要求:
1、在子类中可以使用父类中定义的方法
2、可以通过在子类中增加方法以实现新的功能
3、在子类中重写父类的方法可以改变程序的行为
声明抽象方法的目的:
1、期待子类去实现抽象方法
2、要求子类去实现抽象方法
十八、Visitor模式
Visitor模式的目的是将处理从数据结构中分离出来。
数据结构可以将元素集合和数据关联在一起。保存数据结构与以数据结构为基础进行处理是两
种不同的东西。
开闭原则:对扩展开放,对修改关闭
在不修改现有代码的前提下进行扩展功能就是开闭原则