1.工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。(菜鸟教程)
简单来讲,就是有一个类的工厂,工厂里面专门生产类的方法,有了这个工厂后,我们就可以直接去工厂获取类,而不是自己创建。
例子:(3条消息) Spring中常见的设计模式—工厂模式_spring工厂模式_守夜人爱吃兔子的博客-CSDN博客
2.单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。(菜鸟教程)
单例模式的实现有三种方式,分别为懒汉模式、饿汉模式、枚举法
懒汉模式
/**
* 懒汉模式,单例
*/
public class Singleton {
private static Singleton instance;
public Singleton() {
}
public static Singleton getInstance() {
if (null == instance)
instance = new Singleton();
return instance;
}
}
测试代码
public class SingletonTest {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
Singleton s = Singleton.getInstance();
System.out.println(s.hashCode());
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
Singleton s = Singleton.getInstance();
System.out.println(s.hashCode());
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
利用线程进行测试,可以知道懒汉模式的线程是不安全的,当一个线程还未创建完时,另一个线程也开始创建,会导致创建出两个对象。如何就解决这种问题?可以加上synchronized 。
/**
* 懒汉模式,单例
*/
public class Singleton {
private static Singleton instance;
public Singleton() {
}
public static synchronized Singleton getInstance() {//synchronized设置为同步锁,解决线程安全性
if (null == instance)
instance = new Singleton();
return instance;
}
}
饿汉模式
饿汉模式会利用JVM隔离其他线程,线程是安全的
/**
* 饿汉模式,单例
*/
public class SingleTon02 {
private static SingleTon02 instence = new SingleTon02();
public SingleTon02() {
}
public static SingleTon02 getInstance(){
return instence;
}
}
饿汉模式和懒汉模式的对比
枚举法
实现代码
/**
* 枚举法,单例
*/
public enum SingleTon03 {
INSTANCE;
}
测试代码
public class SingletonTest03 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
SingleTon03 s = SingleTon03.INSTANCE;
System.out.println(s.hashCode());
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
SingleTon03 s = SingleTon03.INSTANCE;
System.out.println(s.hashCode());
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
3.代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。(菜鸟教程)
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
定义接口
package com.wnhz.aop;
public interface Service {
public int add();
public void print();
public int mul();
}
实现类
package com.wnhz.aop;
import org.springframework.stereotype.Component;
@Component(value = "serviceaaaa")
public class ServiceImpl implements Service {
@Override
public int add() {
// int z = 1/0;
int x = 1;
int y = 3;
System.out.println("加法");
return x + y + 3;
}
@Override
public void print() {
System.out.println("打印");
}
@Override
public int mul() {
System.out.println("乘法");
return 100 * 500;
}
}
测试类
package com.wnhz.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
public class AspectTest {
@Before(value = "execution(public * com.wnhz.aop.Service.*())")
public void beforetest(JoinPoint joinPoint){
String methodName= joinPoint.getSignature().getName();
String args = Arrays.toString(joinPoint.getArgs());
System.out.println(methodName+"的-----before-----,参数是:"+args);
}
@After(value = "execution(public * com.wnhz.aop.Service.*())")
public void aftertest(JoinPoint joinPoint){
String methodName= joinPoint.getSignature().getName();
String args = Arrays.toString(joinPoint.getArgs());
System.out.println(methodName+"的-----after-----,参数是:"+args);
}
@AfterReturning(value = "execution(public * com.wnhz.aop.Service.*())")
public void afterreturntest(JoinPoint joinPoint){
String methodName= joinPoint.getSignature().getName();
String args = Arrays.toString(joinPoint.getArgs());
System.out.println(methodName+"的-----after returning-----,参数是:"+args);
}
@AfterThrowing(value = "execution(public * com.wnhz.aop.Service.*())")
public void afterthroetest(JoinPoint joinPoint){
String methodName= joinPoint.getSignature().getName();
String args = Arrays.toString(joinPoint.getArgs());
System.out.println(methodName+"的-----after throwing-----,参数是:"+args);
}
@Around(value = "execution(public * com.wnhz.aop.Service.add(..))")
public Object aroundTest(ProceedingJoinPoint proceedingJoinPoint){
Object obj = null;
try {
System.out.println("before");
obj = proceedingJoinPoint.proceed();
System.out.println("after returning");
} catch (Throwable e) {
System.out.println("throw");
throw new RuntimeException(e);
}finally {
System.out.println("after");
}
return obj;
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
Service service = (Service) context.getBean("serviceaaaa");
service.add();
// service.print();
}
}
测试结果
例子:spring设计模式_代理模式 - wujc_sh - 博客园 (cnblogs.com)
4.模板模式
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。(菜鸟教程)
public abstract class Template {
//这是我们的模板方法
public final void TemplateMethod(){
PrimitiveOperation1();
PrimitiveOperation2();
PrimitiveOperation3();
}
protected void PrimitiveOperation1(){
//当前类实现
}
//被子类实现的方法
protected abstract void PrimitiveOperation2();
protected abstract void PrimitiveOperation3();
}
public class TemplateImpl extends Template {
@Override
public void PrimitiveOperation2() {
//当前类实现
}
@Override
public void PrimitiveOperation3() {
//当前类实现
}
}
5.观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。(菜鸟教程)
它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
6.适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。(菜鸟教程)
例子:Spring中常见的设计模式——适配器模式 - 金色的鱼儿 - 博客园 (cnblogs.com)
7.装饰器模式
装饰器模式:动态的给一个对象添加一些额外的功能。
Spring 的 ApplicationContext 中配置所有的 DataSource。这些 DataSource 可能是不同的数据库,然后 SessionFactory 根据用户的每次请求,将 DataSource 设置成不同的数据源,以达到切换数据源的目的。
在 Spring 中有两种表现:
一种是类名中含有 Wrapper;另一种是类名中含有 Decorator。
例子:(3条消息) Spring设计模式之装饰器模式_dufufd的博客-CSDN博客
8.策略模式
策略模式(Strategy Pattern) 定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互替换,让算法独立于使用它的客户而独立变化。