设计模式简要学习
策略模式
它定义了一系列的算法,将每个算法封装起来,并使它们可以互相替换。策略模式使得算法的变化独立于使用算法的客户端。
适用场景:
- 当一个系统中有多个算法,需要动态切换时。
- 当一个类有多个行为,可以通过定义不同的策略来实现这些行为。
- 当算法的变化不应该影响到使用算法的客户端时。
装饰器模式
装饰器设计模式是一种结构型的设计模式,它允许我们在运行时动态地给一个对象添加额外的行为,并且不需要修改原有的类。它可以有效地避免类爆炸问题,提高代码的可维护性和复用性。同时,装饰器模式也具有灵活、可扩展和易于维护等优点,是一种非常实用和常用的设计模式。
使用装饰器模式时,我们将新增的行为包装在一个装饰器类中,与原有类具有相同的接口。这个装饰器类可以包含一个对于原有类的引用,在调用原有类的方法之前或之后执行额外的逻辑,从而实现对原有类的增强。
装饰器模式的核心思想就是「包装」,通过不断地向对象上叠加新的行为,使得对象具有了更多的功能和特性,同时保持了对象的原有接口和结构不变
总结
装饰器设计模式是一种结构型设计模式,它允许在不改变原有对象的基础上,动态地添加新的行为或修改已有行为;
通过将对象传递给装饰器函数或类,可以创建一个包装对象,该对象可以在执行原始对象的操作之前或之后执行其他操作;
这种模式使得代码更加灵活和可扩展,而不需要在原始对象中硬编码所有可能的变体
模板方法模式
模板模式是一种行为型设计模式,它定义了一个算法的骨架,并允许子类重写特定步骤的实现方式。模板模式将算法的通用部分放在一个抽象父类中,而将不同的实现细节留给具体的子类去实现。当我们需要在多个类之间共享某些相同的行为时,可以考虑使用模板方法模式。
模板模式常常被用来处理算法的变化和复杂性,尤其是当算法需要多个步骤、每个步骤的实现方式不同、以及需要在运行时动态决定算法的具体实现时。通过使用模板模式,我们可以避免代码重复,并且为子类提供一个清晰的框架,以便于更好地组织代码逻辑。
模板模式通常由两部分组成:抽象父类和具体子类。抽象父类包含了算法的高层次结构,而具体子类则负责实现算法的具体步骤。通常情况下,抽象父类会定义算法的骨架,也就是算法所需的各个步骤以及它们之间的关系。具体子类则会实现这些步骤的具体实现方式。
模板方法模式的应用场景
以下是一些模板方法模式的应用场景:
数据库操作:在进行数据库操作时,我们可能需要执行一系列相同的步骤,例如连接数据库、执行 SQL 查询、处理结果等。这些步骤可以抽象成一个模板方法,而每个具体的数据库操作可以通过继承该模板方法并重写其中的某些步骤来实现;
游戏开发:在游戏开发中,我们可能需要编写一些游戏关卡和任务,这些关卡和任务都有一些通用的流程,例如初始化、开始、结束等。这些流程可以抽象成一个模板方法,而每个具体的游戏关卡和任务可以通过继承该模板方法并重写其中的某些步骤来实现;
软件框架:在软件框架开发中,我们可能需要为用户提供一些基础功能,例如日志记录、异常处理等。这些功能可以抽象成一个模板
迭代器模式
迭代器模式。对应java中的具体demo是iterator遍历接口。本质就是,针对不同对象,比如list,tree,list等不同容器的遍历,如果每一个都交给客户端实现,不利于维护。所以使用迭代器模式,提供一个统一的用来遍历,客户不需要关注具体实现。
代理模式
静态代理,动态代理。解决什么问题? 原来的类,不能修改,这个时候,通过一个代理类,实现增强,修改原来类的功能。
java中动态代理使用非常广泛。AOP等很多技术都是基于动态代理来实现。
门面模式
- 定义:门面模式是为子系统提供一组统一的接口,定义一组高层接口,让子系统更容易使用。
- 比如:一个系统A,提供a,b,c,d四个接口。利用门面模式,我们提供一个包裹a,b,c,d接口调用的门面接口X给系统B直接使用。
享元模式
摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,从而让我们能在有限的内存容量中载入更多对象。
要解决什么问题?
节约内存的空间大小。
java小demo实现
import java.util.HashMap;
// 享元工厂类
class ShapeFactory {
private static final HashMap<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String color) {
Circle circle = (Circle) shapeMap.get(color);
if (circle == null) {
circle = new Circle(color);
shapeMap.put(color, circle);
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
// 抽象享元类
interface Shape {
void draw();
}
// 具体享元类
class Circle implements Shape {
private String color;
public Circle(String color) {
this.color = color;
}
@Override
public void draw() {
System.out.println("Drawing circle with color : " + color);
}
}
// 客户端代码
public class FlyweightPatternDemo {
private static final String[] colors = {"Red", "Green", "Blue", "Yellow", "Black"};
public static void main(String[] args) {
for (int i = 0; i < 10; ++i) {
Circle circle = (Circle) ShapeFactory.getShape(getRandomColor());
circle.draw();
}
}
private static String getRandomColor() {
return colors[(int) (Math.random() * colors.length)];
}
}
在这个示例中,ShapeFactory 是享元工厂类,负责创建和管理享元对象。Circle 类是具体的享元类,表示一个圆形对象。FlyweightPatternDemo 类是客户端代码,演示了如何使用享元模式来共享相似对象的状态。在 main 方法中,我们创建了 10 个圆形对象,但只创建了 5 个不同颜色的圆形对象,因为相同颜色的圆形对象会被共享。
优缺点
优点:
- 内存利用率提高: 通过共享相似对象的部分状态,可以大大减少系统中对象的数量,从而节省内存空间。
- 性能提升: 减少了对象的数量,从而减少了对象的创建和销毁所需的时间,提高了系统的性能。
- 可维护性增强: 享元模式将共享状态分离出来,使得修改状态时只需修改共享部分,不影响其他对象,易于维护和扩展。
- 灵活性增强: 可以灵活地组合享元对象来创建新的对象,从而满足不同场景的需求。
缺点: - 复杂性增加: 实现享元模式可能需要将对象的状态分为内部状态和外部状态,增加了系统的复杂性。
- 可能引起线程安全问题: 如果享元对象被多个线程共享,并且存在可变状态,可能需要额外的同步措施来保证线程安全。
- 可能导致系统过度优化: 在一些情况下,过度使用享元模式可能会导致代码的可读性降低,使得系统变得过度优化,不易理解。
- 不适用于所有情况: 享元模式适用于需要创建大量相似对象的情况,但并不适用于所有情况,如果对象的状态变化较多或者不可共享,则不适合使用享元模式。
责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求为止。在责任链模式中,每个处理者都包含对下一个处理者的引用,形成一个链条。请求从链条的头部开始传递,直到找到合适的处理者为止。
责任链模式的主要组成部分包括:
抽象处理者(Handler):定义了一个处理请求的接口,并包含一个对下一个处理者的引用。通常会提供一个处理请求的方法。
具体处理者(Concrete Handler):实现了抽象处理者接口,并根据自身能力来决定是否能够处理请求。如果自己能够处理,则进行处理;否则将请求传递给下一个处理者。
责任链模式的工作原理是,当客户端发起一个请求时,请求会从责任链的头部开始传递,每个处理者检查自己是否能够处理该请求。如果能够处理,则处理请求并返回结果;否则将请求传递给下一个处理者。这样,请求会依次沿着责任链传递,直到有一个处理者处理了该请求为止。
责任链模式的优点包括:
解耦请求发送者和接收者:请求发送者无需知道处理请求的具体处理者,只需将请求发送给责任链的头部即可。
可扩展性:可以很容易地添加新的处理者或调整处理者的顺序,以满足不同的需求。
灵活性:每个处理者都可以自行决定是否处理请求,以及如何处理请求,从而使得系统更加灵活。
责任链模式常用于以下场景:
多个对象可以处理同一请求,但具体处理者在运行时确定。
需要动态指定处理链条的情况。
在不明确指定接收者的情况下,向多个对象中的一个发送请求。
总的来说,责任链模式能够有效地降低系统的耦合度,提高代码的灵活性和可维护性,是一种常用的设计模式。
文章部分来源:
作者:LeetCode
链接:https://leetcode.cn/leetbook/read/java-interview-breakthrough/7tm2t2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。