一、工厂模式
这里只讲简单工厂模式,详细的可以参考Java工厂模式(随笔)-CSDN博客。工厂类会根据不同的参数或条件来决定创建哪种对象,这样客户端只需要知道自己需要什么对象,而不需要关心对象的创建过程!
代码实现如下
1)首先是Phone接口
package factory;
/**
* @author heming
* @date 2024/5/31
* 抽象电话的接口
*/
public interface Phone {
/**
* 抽象的打电话的功能,有不同的实现类做具体的实现
*/
void call();
}
2)创建几个实现接口的方法的手机类方便测试
2.1、创建华为手机类
package factory;
/**
* @author heming
* @date 2023/5/31
*/
public class HuaweiPhone implements Phone {
@Override
public void call() {
System.out.println("使用华为手机打电话");
}
}
2.2、创建IPhone手机类
package factory;
/**
* @author heming
* @date 2024/5/31
*/
public class IPhone implements Phone {
@Override
public void call() {
System.out.println("使用Iphone打电话");
}
}
2.3、创建MIphone手机类
package factory;
/**
* @author heming
* @date 2023/5/31
*/
public class MiPhone implements Phone {
@Override
public void call() {
System.out.println("使用MiPhone打电话");
}
}
3)创建简单工厂模式类
通过简单工厂模式类实现相关业务逻辑
package factory;
/***
* @Date(时间)2023-05-31
* @Author heming
*
* 简单工厂模式类
*/
public class SimpleFactoryPattern {
/**
* 简单的工厂
* @param name 需要创建对象的名称
* @return
*/
public static Phone create(String name) {
//根据输入对象名称判断返回相匹配的对象
if("IPhone".equals(name)) {
//返回对象
return new IPhone();
}else if("MiPhone".equals(name)) {
return new MiPhone();
}else if("HuaweiPhone".equals(name)) {
return new HuaweiPhone();
}
return null;
}
}
代码测试:
package factory;
/***
* @Date(时间)2023-06-01
* @Author heming
*/
public class Mains {
public static void main(String[] args) {
Phone phone = SimpleFactoryPattern.create("IPhone");
phone.call();
Phone phone2 = SimpleFactoryPattern.create("MiPhone");
phone2.call();
Phone phone3 = SimpleFactoryPattern.create("HuaweiPhone");
phone3.call();
}
}
二、单例模式
单例模式是一种常见的设计模式,可以确保一个类只有一个实例,并提供全局访问点。在合适的情况下,合理使用单例模式可以提高系统的性能和可维护性。
在Java中,可以使用以下几种方式来实现单例模式:
- 饿汉式:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
// 私有构造方法
}
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式(线程安全):
public class Singleton {
private static Singleton instance;
private Singleton() {
// 私有构造方法
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式(双重检查锁定):
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
// 私有构造方法
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静态内部类:
public class Singleton {
private Singleton() {
// 私有构造方法
}
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
三、代理设计模式
代理模式在 AOP 中的应用
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理。
四、模板方法模式
模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤的实现方式。
package template;
public abstract class Template {
//这是我们的模板方法
public final void TemplateMethod(){
PrimitiveOperation1();
PrimitiveOperation2();
PrimitiveOperation3();
}
protected void PrimitiveOperation1(){
//当前类实现
System.out.println("PrimitiveOperation1");
}
//被子类实现的方法
protected abstract void PrimitiveOperation2();
protected abstract void PrimitiveOperation3();
}
package template;
public class TemplateImpl extends Template {
@Override
public void PrimitiveOperation2() {
//当前类实现
System.out.println("PrimitiveOperation2");
}
@Override
public void PrimitiveOperation3() {
//当前类实现
System.out.println("PrimitiveOperation3");
}
}
验证
package template;
public class TemplateMain {
public static void main(String[] args) {
Template template = new TemplateImpl();
template.PrimitiveOperation1();
template.PrimitiveOperation2();
template.PrimitiveOperation3();
}
}
Spring 中 jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。一般情况下,我们都是使用继承的方式来实现模板模式,但是 Spring 并没有使用这种方式,而是使用Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时增加了灵活性。
五、观察者模式
观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
Spring 事件驱动模型中的三种角色
事件角色
ApplicationEvent
(org.springframework.context
包下)充当事件的角色,这是一个抽象类,它继承了java.util.EventObject
并实现了 java.io.Serializable
接口。
Spring 中默认存在以下事件,他们都是对 ApplicationContextEvent
的实现(继承自ApplicationContextEvent
):
-
ContextStartedEvent
:ApplicationContext
启动后触发的事件; -
ContextStoppedEvent
:ApplicationContext
停止后触发的事件; -
ContextRefreshedEvent
:ApplicationContext
初始化或刷新完成后触发的事件; -
ContextClosedEvent
:ApplicationContext
关闭后触发的事件。
事件监听者角色
ApplicationListener
充当了事件监听者角色,它是一个接口,里面只定义了一个 onApplicationEvent()
方法来处理ApplicationEvent
。ApplicationListener
接口类源码如下,可以看出接口定义看出接口中的事件只要实现了 ApplicationEvent
就可以了。所以,在 Spring中我们只要实现 ApplicationListener
接口实现 onApplicationEvent()
方法即可完成监听事件
package org.springframework.context; import java.util.EventListener; @FunctionalInterface public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E var1); }
事件发布者角色
ApplicationEventPublisher
充当了事件的发布者,它也是一个接口。
@FunctionalInterface public interface ApplicationEventPublisher { default void publishEvent(ApplicationEvent event) { this.publishEvent((Object)event); } void publishEvent(Object var1); }
ApplicationEventPublisher
接口的publishEvent()
这个方法在AbstractApplicationContext
类中被实现,阅读这个方法的实现,你会发现实际上事件真正是通过ApplicationEventMulticaster
来广播出去的。具体内容过多,就不在这里分析了,后面可能会单独写一篇文章提到。
Spring 的事件流程总结
-
定义一个事件: 实现一个继承自
ApplicationEvent
,并且写相应的构造函数; -
定义一个事件监听者:实现
ApplicationListener
接口,重写onApplicationEvent()
方法; -
使用事件发布者发布消息: 可以通过
ApplicationEventPublisher
的publishEvent()
方法发布消息。
Example:
package mode.observe;
import org.springframework.context.ApplicationEvent;
// 定义一个事件,继承自ApplicationEvent并且写相应的构造函数
public class DemoEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private String message;
public DemoEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
package mode.observe;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
// 定义一个事件监听者,实现ApplicationListener接口,重写 onApplicationEvent() 方法;
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
//使用onApplicationEvent接收消息
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMessage();
System.out.println("接收到的信息是:"+msg);
}
}
package mode.observe;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
// 发布事件,可以通过ApplicationEventPublisher 的 publishEvent() 方法发布消息。
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(String message){
//发布事件
applicationContext.publishEvent(new DemoEvent(this, message));
}
}
测试类如下:
当调用 DemoPublisher
的 publish()
方法的时候,比如 demoPublisher.publish("你好")
,控制台就会打印出:接收到的信息是:你好
。
六、适配器模式
七、装饰者模式