设计模式学习35问笔记

本文深入探讨了设计模式的概念及其重要性,包括单例模式、工厂模式、值对象模式、DAO模式等常见设计模式的定义、应用场景及解决方案。通过实例解析,展示了如何在Java编程中使用这些模式提高代码的可扩展性和可维护性。此外,文章还讨论了开放-封闭法则、替换法则等设计原则,并提及了在JDK中常见的设计模式实例。最后,提出了在实际项目中综合运用设计模式构建应用程序结构的策略。

1、什么是设计模式?

就是经过实践验证的⽤来解决特定环境下特定问题的解决⽅案
2、设计模式⽤来⼲什么?
寻找合适的对象
决定对象的粒度
指定对象的接⼝
描述对象的实现
运⽤复⽤机制
重复使⽤经过实践验证的正确的,⽤来解决某⼀类问题的解决⽅案来达到减少⼯作
量、提⾼正确率等⽬的
3、什么是对象粒度?
对象中⽅法的多少就是粒度
4、基本的 Java 编程设计应遵循的规则?
⾯向接⼝编程,优先使⽤对象组合
5、设计模式的应⽤范围
所能解决的特定的⼀类问题中6、简述什么是单例模式,以及他解决的问题,应⽤的环境,解决的⽅案,模式的本质
在任何时间内只有⼀个类实例存在的模式,需要有⼀个从中进⾏全局访问和维护某种
类型数据的区域的环境下使⽤单例模式,解决⽅案就是保证⼀个类只有⼀个类实例存
在,本质就是实例共⽤同⼀块内存区域
7、简述什么是⼯⼚模式,以及他解决的问题,应⽤的环境,解决的⽅案,模式的本质
利⽤⼯⼚来解决接⼝选择的问题的模式
应⽤环境:当⼀个类⽆法预料要创建哪种类的对象或是⼀个类需要由⼦类来指定
创建的对象时,就需要⽤到⼯⼚模式
解决⽅案:定义⼀个创建对象的接⼝,让⼦类来决定具体实例化哪⼀个类
本质就是根据不同的情况来选择不同的接⼝
8、述什么是值对象模式,以及他解决的问题,应⽤的环境,解决的⽅案,模式的本质
⽤来把⼀组数据封装成⼀个对象的模式
解决问题:在远程⽅法的调⽤次数增加的时候,相关的应⽤程序性能将会有很⼤的下
解决⽅案:使⽤值对象的时候,可以通过仅仅⼀次⽅法调⽤来取得整个对象,⽽不是
使⽤多次⽅法调⽤以得到对象中每个域的数值
本质:就是把需要传递的多个值封装成⼀个对象⼀次性传过去
10、简述什么是 DAO 模式,以及他解决的问题,应⽤的环境,解决的⽅案,模式的本质
数据访问对象
解决问题:根据数据源不同,数据访问也不同。根据存储的类型(关系数据库、
⾯向对象数据库、纯⽂件等)和供应商实现不同,持久性存储(如数据库)的访问差
别也很⼤。如何对存储层以外的模块屏蔽这些复杂性,以提供统⼀的调⽤存储实现。
程序的分布式问题
解决⽅案:将数据访问逻辑抽象为特殊的资源,也就是说将系统资源的接⼝从
其底层访问机制中隔离出来;通过将数据访问的调⽤打包,数据访问对象可以
促进对于不同数据库类型和模式的数据访问。
DAO 的本质就是⼀层屏蔽⼀种变化
本质:分层,是系统组件和数据源中间的适配器。(⼀层屏蔽⼀种变化)
什么是开放-封闭法则(OCP)
可扩展但是不可以更改已有的模块
对扩展是开放的 对修改是封闭
什么是替换法则(LSP)
使⽤指向基类(超类)的引⽤的函数,必须能够在不知道具体派⽣类(⼦类)对象类
型的情况下使⽤
14、如何综合使⽤我们学过的设计模式来构建合理的应⽤程序结构
是采⽤接⼝进⾏隔离,然后同时暴露值对象和⼯⼚类,如果是需要数据存储的功能,
⼜会通过 DAO 模式去与数据存储层交互。
15、请列举出在 JDK 中⼏个常⽤的设计模式?
单例模式(Singleton pattern)⽤于 RuntimeCalendar 和其他的⼀些类中;
⼯⼚模式(Factory pattern)被⽤于各种不可变的类如 Boolean,像 Boolean.valueOf
观察者模式(Observer pattern)被⽤于 Swing 和很多的事件监听中;
装饰器设计模式(Decorator design pattern)被⽤于多个 Java IO 类中。
16、什么是设计模式?你是否在你的代码⾥⾯使⽤过任何设计模式?
设计模式是世界上各种各样程序员⽤来解决特定设计问题的尝试和测试的⽅法。设计
模式是代码可⽤性的延伸。17Java 中什么叫单例设计模式?请⽤ Java 写出线程安全的单例模式
单例模式重点在于在整个系统上共享⼀些创建时较耗资源的对象。整个应⽤中只维护
⼀个特定类实例,它被所有组件共同使⽤。Java.lang.Runtime 是单例模式的经典例⼦。
Java 5 开始你可以使⽤枚举(enum)来实现线程安全的单例。
18、在 Java 中,什么叫观察者设计模式(observer design pattern)?
观察者模式是基于对象的状态变化和观察者的通讯,以便他们作出相应的操作。简单
的例⼦就是⼀个天⽓系统,当天⽓变化时必须在展示给公众的视图中进⾏反映。这个
视图对象是⼀个主体,⽽不同的视图是观察者。
19、使⽤⼯⼚模式最主要的好处是什么?在哪⾥使⽤?
⼯⼚模式的最⼤好处是增加了创建对象时的封装层次。如果你使⽤⼯⼚来创建对象,
之后你可以使⽤更⾼级和更⾼性能的实现来替换原始的产品实现或类,这不需要在调
⽤层做任何修改。
20、举⼀个⽤ Java 实现的装饰模式(decorator design pattern)?它是作⽤于对象层次还
是类层次?
装饰模式增加强了单个对象的能⼒。Java IO 到处都使⽤了装饰模式,典型例⼦就是
Buffered 系列类如 BufferedReader BufferedWriter,它们增强了 Reader Writer
象,以实现提升性能的 Buffer 层次的读取和写⼊。21、在 Java 中,为什么不允许从静态⽅法中访问⾮静态变量?
Java 中不能从静态上下⽂访问⾮静态数据只是因为⾮静态变量是跟具体的对象实例关
联的,⽽静态的却没有和任何实例关联。
22、设计⼀个 ATM 机,请说出你的设计思路?
⽐如设计⾦融系统来说,必须知道它们应该在任何情况下都能够正常⼯作。不管是断
电还是其他情况,ATM 应该保持正确的状态(事务) , 想想 加锁(locking)、事务
transaction)、错误条件(error condition)、边界条件(boundary condition) 等
等。尽管你不能想到具体的设计,但如果你可以指出⾮功能性需求,提出⼀些问题,
想到关于边界条件,这些都会是很好的。
23、在 Java 中,什么时候⽤重载,什么时候⽤重写?
如果你看到⼀个类的不同实现有着不同的⽅式来做同⼀件事,那么就应该⽤重写
overriding),⽽重载(overloading)是⽤不同的输⼊做同⼀件事。在 Java 中,重载
的⽅法签名不同,⽽重写并不是。
24、举例说明什么情况下会更倾向于使⽤抽象类⽽不是接⼝?
接⼝和抽象类都遵循⾯向接⼝⽽不是实现编码设计原则,它可以增加代码的灵活
性,可以适应不断变化的需求。下⾯有⼏个点可以帮助你回答这个问题:
Java 中,你只能继承⼀个类,但可以实现多个接⼝。所以⼀旦你继承了⼀个类,你
就失去了继承其他类的机会了。
接⼝通常被⽤来表示附属描述或⾏为如:RunnableClonableSerializable 等等,因此
当你使⽤抽象类来表示⾏为时,你的类就不能同时是 Runnable Clonable(注:这⾥的
意思是指如果把 Runnable 等实现为抽象类的情况),因为在 Java 中你不能继承两个
类,但当你使⽤接⼝时,你的类就可以同时拥有多个不同的⾏为。
在⼀些对时间要求⽐较⾼的应⽤中,倾向于使⽤抽象类,它会⽐接⼝稍快⼀点。
如果希望把⼀系列⾏为都规范在类继承层次内,并且可以更好地在同⼀个地⽅进⾏编
码,那么抽象类是⼀个更好的选择。有时,接⼝和抽象类可以⼀起使⽤,接⼝中定义
函数,⽽在抽象类中定义默认的实现。
25、你所知道的设计模式有哪些?
Java 中⼀般认为有 23 种设计模式,我们不需要所有的都会,但是其中常⽤的⼏种设
计模式应该去掌握。下⾯列出了所有的设计模式。需要掌握的设计模式已经单独列出
来了,当然能掌握的越多越好。
总体来说设计模式分为三⼤类:
l创建型模式,共五种:⼯⼚⽅法模式、抽象⼯⼚模式、单例模式、建造者模式、原型
模式。
l结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、
组合模式、享元模式。
l⾏为型模式,共⼗⼀种:策略模式、模板⽅法模式、观察者模式、迭代⼦模式、责任
链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模
式。
26、单例设计模式?
最好理解的⼀种设计模式,分为懒汉式和饿汉式。
饿汉式:
public class Singleton {
// 直接创建对象
public static Singleton instance = new Singleton();
// 私有化构造函数
private Singleton() {
}
// 返回对象实例
public static Singleton getInstance() {
return instance;
}
}
懒汉式:
public class Singleton {
// 声明变量
private static volatile Singleton singleton = null;
// 私有构造函数
private Singleton() {
}
// 提供对外方法
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}27、⼯⼚设计模式?
⼯⼚模式分为⼯⼚⽅法模式和抽象⼯⼚模式。
⼯⼚⽅法模式分为三种:
l普通⼯⼚模式,就是建⽴⼀个⼯⼚类,对实现了同⼀接⼝的⼀些类进⾏实例的创建。
多个⼯⼚⽅法模式,是对普通⼯⼚⽅法模式的改进,在普通⼯⼚⽅法模式中,如果传
递的字符串出错,则不能正确创建对象。
l多个⼯⼚⽅法模式,是提供多个⼯⼚⽅法,分别创建对象。
l静态⼯⼚⽅法模式,将上⾯的多个⼯⼚⽅法模式⾥的⽅法置为静态的,不需要创建实
例,直接调⽤即可。
n普通⼯⼚模式
public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mail sender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {System.out.println("请输入正确的类型!");
return null;
}
}
}
n多个⼯⼚⽅法模式
该模式是对普通⼯⼚⽅法模式的改进,在普通⼯⼚⽅法模式中,如果传递的字符串出
错,则不能正确创建对象,⽽多个⼯⼚⽅法模式是提供多个⼯⼚⽅法,分别创建对
象。
public class SendFactory {
public Sender produceMail() {
return new MailSender();
}
public Sender produceSms() {
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.send();
}
}
n静态⼯⼚⽅法模式
将上⾯的多个⼯⼚⽅法模式⾥的⽅法置为静态的,不需要创建实例,直接调⽤即可。
public class SendFactory {
public static Sender produceMail() {
return new MailSender();
}
public static Sender produceSms() {
return new SmsSender();
}
}
public class FactoryTest {public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.send();
}
}
n抽象⼯⼚模式
⼯⼚⽅法模式有⼀个问题就是,类的创建依赖⼯⼚类,也就是说,如果想要拓展程
序,必须对⼯⼚类进⾏修改,这违背了闭包原则,所以,从设计⻆度考虑,有⼀定的
问题,如何解决?就⽤到抽象⼯⼚模式,创建多个⼯⼚类,这样⼀旦需要增加新的功
能,直接增加新的⼯⼚类就可以了,不需要修改之前的代码。
public interface Provider {
public Sender produce();
}
public interface Sender {
public void send();
}
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("this is mail sender!");
}
}
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("this is sms sender!");
}
}
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
public class SendMailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();}
}
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.send();
}
}
28、建造者模式(Builder
⼯⼚类模式提供的是创建单个类的模式,⽽建造者模式则是将各种产品集中起来进⾏
管理,⽤来创建复合对象, 所谓复合对象就是指某个类具有不同的属性,其实建造者
模式就是前⾯抽象⼯⼚模式和最后的 Test 结合起来得到的。
public class Builder {
private List<Sender> list = new ArrayList<Sender>();
public void produceMailSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new MailSender());
}
}
public void produceSmsSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new SmsSender());
}
}
}
public class Builder {
private List<Sender> list = new ArrayList<Sender>();
public void produceMailSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new MailSender());
}
}
public void produceSmsSender(int count) {
for (int i = 0; i < count; i++) {
list.add(new SmsSender());
}
}}
public class TestBuilder {
public static void main(String[] args) {
Builder builder = new Builder();
builder.produceMailSender(10);
}
}
29、适配器设计模式
适配器模式将某个类的接⼝转换成客户端期望的另⼀个接⼝表示,⽬的是消除由于接
⼝不匹配所造成的类的兼容性问题。主要分为三类:类的适配器模式、对象的适配器
模式、接⼝的适配器模式。
n类的适配器模式
public class Source {
public void method1() {
System.out.println("this is original method!");
}
}
public interface Targetable {
/* 与原类中的方法相同 */
public void method1();
/* 新类的方法 */
public void method2();
}
public class Adapter extends Source implements Targetable {
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
}
public class AdapterTest {
public static void main(String[] args) {
Targetable target = new Adapter();
target.method1();
target.method2();
}
}n对象的适配器模式
基本思路和类的适配器模式相同,只是将 Adapter 类作修改,这次不继承 Source
类,⽽是持有 Source 类的实例,以达到解决兼容性的问题。
public class Wrapper implements Targetable {
private Source source;
public Wrapper(Source source) {
super();
this.source = source;
}
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
@Override
public void method1() {
source.method1();
}
}
public class AdapterTest {
public static void main(String[] args) {
Source source = new Source();
Targetable target = new Wrapper(source);
target.method1();
target.method2();
}
}
n接⼝的适配器模式
接⼝的适配器是这样的:有时我们写的⼀个接⼝中有多个抽象⽅法,当我们写该接⼝
的实现类时,必须实现该接⼝的所有⽅法,这明显有时⽐较浪费,因为并不是所有的
⽅法都是我们需要的,有时只需要某⼀些,此处为了解决这个问题,我们引⼊了接⼝
的适配器模式,借助于⼀个抽象类,该抽象类实现了该接⼝,实现了所有的⽅法,⽽
我们不和原始的接⼝打交道,只和该抽象类取得联系,所以我们写⼀个类,继承该抽
象类,重写我们需要的⽅法就⾏。30、装饰模式(Decorator
顾名思义,装饰模式就是给⼀个对象增加⼀些新的功能,⽽且是动态的,要求装饰对
象和被装饰对象实现同⼀个接⼝,装饰对象持有被装饰对象的实例。
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Decorator implements Sourceable {
private Sourceable source;
public Decorator(Sourceable source) {
super();
this.source = source;
}
@Override
public void method() {
System.out.println("before decorator!");
source.method();
System.out.println("after decorator!");
}
}
public class DecoratorTest {
public static void main(String[] args) {
Sourceable source = new Source();
Sourceable obj = new Decorator(source);
obj.method();
}
}31、策略模式(strategy
策略模式定义了⼀系列算法,并将每个算法封装起来,使他们可以相互替换,且算法
的变化不会影响到使⽤算法的客户。需要设计⼀个接⼝,为⼀系列实现类提供统⼀的
⽅法,多个实现类实现该接⼝,设计⼀个抽象类(可有可⽆,属于辅助类),提供辅
助函数。策略模式的决定权在⽤户,系统本身提供不同算法的实现,新增或者删除算
法,对各种算法做封装。因此,策略模式多⽤在算法决策系统中,外部⽤户只需要决
定⽤哪个算法即可。
public interface ICalculator {
public int calculate(String exp);
}
public class Minus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp"-");
return arrayInt[0] - arrayInt[1];
}
}
public class Plus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp"\+");
return arrayInt[0] + arrayInt[1];
}
}
public class AbstractCalculator {
public int[] split(String expString opt) {
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
public class StrategyTest {
public static void main(String[] args) {
String exp = "2+8";ICalculator cal = new Plus();
int result = cal.calculate(exp);
System.out.println(result);
}
}
32、观察者模式(Observer
观察者模式很好理解,类似于邮件订阅和 RSS 订阅,当我们浏览⼀些博客或 wiki 时,
经常会看到 RSS 图标,就这的意思是,当你订阅了该⽂章,如果后续有更新,会及时
通知你。其实,简单来讲就⼀句话:当⼀个对象变化时,其它依赖该对象的对象都会
收到通知,并且随着变化!对象之间是⼀种⼀对多的关系。
public interface Observer {
public void update();
}
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
public interface Subject {
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while (enumo.hasMoreElements()) {
enumo.nextElement().update();
}
}
}
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("update self!");
notifyObservers();
}
}
public class ObserverTest {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
33、微服务架构的六种常⽤设计模式是什么?
代理设计模式
聚合设计模式
链条设计模式
聚合链条设计模式数据共享设计模式
异步消息设计模式
34、设计模式是什么,设计模式有什么作⽤?
设计模式是⼀套被反复使⽤的、多数⼈知晓、经过分类编⽬的优秀代码设计经验的总
结。特定环境下特定问题的处理⽅法。
1)重⽤设计和代码 重⽤设计⽐重⽤代码更有意义,⾃动带来代码重⽤
2)提⾼扩展性 ⼤量使⽤⾯向接⼝编程,预留扩展插槽,新的功能或特性很容易加⼊
到系统中来
3)提⾼灵活性 通过组合提⾼灵活性,可允许代码修改平稳发⽣,对⼀处修改不会波
及到其他模块
4) 提⾼开发效率 正确使⽤设计模式,可以节省⼤量的时间
35Spring 框架中都⽤到了哪些设计模式?
Spring 框架中使⽤到了⼤量的设计模式,下⾯列举了⽐较有代表性的:
代理模式AOP remoting 中被⽤的⽐较多。
单例模式spring 配置⽂件中定义的 bean 默认为单例模式。
模板⽅法⽤来解决代码重复的问题。⽐如. RestTemplate, JmsTemplate, JpaTemplate
前端控制器—Spring 提供了 DispatcherServlet 来对请求进⾏分发。
视图帮助(View Helper )—Spring 提供了⼀系列的 JSP 标签,⾼效宏来辅助将分散的代码
整合在视图⾥。依赖注⼊贯穿于 BeanFactory / ApplicationContext 接⼝的核⼼理念。
⼯⼚模式—BeanFactory ⽤来创建对象的实例
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值