结合Java大白话总结23种传统设计模式

建议在学习设计模式之前先了解设计原则,可以参考:

结合Java大白话总结7种传统设计原则icon-default.png?t=N7T8https://blog.csdn.net/qq_15029233/article/details/141504139

传统设计模式可以分为三类:

  1. 创建型模式(4+1种):用于将对象的创建和使用分离,使创建对象时更加灵活可控,而不是简单地new。分为单例模式、工厂模式+抽象工厂模式、原型模式、建造者模式
  2. 结构型模式(7种):用于组合类和对象。分为代理模式、适配器模式、装饰者模式、桥接模式、外观模式、组合模式、享元模式
  3. 行为型模式(11种):用于实现对象之间的相互作用。分为模板方法模式、策略模式、命令模式、责任链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式

 一、创建型模式

1、单例模式

定义:确保一个类只有一个实例

分类:

  • 饿汉式:类加载实例对象就创建,可以直接new静态代码块new
  • 懒汉式:首次使用对象时才会创建,可以synchronized线程安全方式、静态内部类new 

应用场景:

  • 类只需要单个实例:配置类,日志类,数据库连接池等
  • 集中管理共享状态 

 饿汉式代码示例:

public class Singleton {    // 饿汉式方式1 直接new
	private Singleton() {}    // 私有构造函数,防止直接实例化

	private static Singleton instance = new Singleton();

	public static Singleton getInstance() {
		return instance;
	}
}

public class Singleton {    // 饿汉式方式2 静态代码块new
	private Singleton() {}

	private static Singleton instance;

	static {
		instance = new Singleton();
	}

	public static Singleton getInstance() {
		return instance;
	}
}

 懒汉式代码示例:

public class Singleton {    // 懒汉式方式1 synchronized块中new
	private Singleton() {}
	private static Singleton instance;

	public static synchronized Singleton getInstance() {    // 保证线程安全
		if(instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}

public class Singleton {    // 懒汉式方式2 静态内部类中new
	private Singleton() {}

	private static class SingletonHolder {
		private static final Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return SingletonHolder.INSTANCE;
	}
} 

解决反序列化创建对象问题:在单例类中加入readResolve()方法,反序列化时会自动调用,用于替代反序列化创建的对象

public class Singleton implements Serializable { 
	private static final long serialVersionUID = 1L;
	private Singleton() {}

	private static class SingletonHolder {
		private static final Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return SingletonHolder.INSTANCE;
	}
	
	private Object readResolve() {
		return SingletonHolder.INSTANCE;
	}
}

解决反射破坏单例问题:思路为在构造函数中加入检查,如果实例已经存在,则抛出异常。或者通过枚举实现单例模式 

public enum Singleton {    // 枚举实现单例模式
	INSTANCE;
	private int value;
	Singleton() {
		value = 6;
	}

	public int getValue() {
		return value;
	}
}

public static void main(String[] args) {
	Singleton singleton = Singleton.INSTANCE;
	int val = singleton.getValue();
}

2、工厂模式(抽象工厂模式)

定义:创建对象工作交给工厂类来做,我们只需要跟工厂类拿对象就好

分类:

  • 简单工厂模式:if.else实现,违背开闭原则
  • 工厂方法模式:接口实现
  • 抽象工厂模式:类似工厂方法,但它是创建一系列相关对象。说白了你买车的时候,车本体类+智能座舱类+智驾驾驶类组成一个套餐一块买

应用场景:

  • 需要创建的对象种类较多,但不确定具体是哪一种时:创建不同类型的数据库连接器MySQL、PostgreSQL等
  • 需要在运行时决定创建哪种类的对象时

简单工厂模式代码示例:

public class SimpleCarFactory {    // if流简单判断,后期添加新车类需要修改源代码,违背开闭原则
	public static Car createCar(String type) {
		Car car = null;
		if("XiaomiSu7".equals(type)) {
			car = new XiaomiCar();
		} else if("ZhijieS7".equals(type)) {
			car = new ZhijieCar();
		}
		return car;
	}
}

工厂方法模式代码示例:

public interface CarFactory {    // 后期添加新车型只需要实现接口
	Car createCar();
}

public class XiaomiCarFactory implements CarFactory {    // 小米汽车实现类
	public Car createCar() {
		return new XiaomiCar();
	}
}

public class ZhijieCarFactory implements CarFactory {    // 智界汽车实现类
	public Car createCar() {
		return new ZhijieCar();
	}
}

public class CarStore {    // 4S店类
	private CarFactory factory;

	public CarStore(CarFactory factory) {
		this.factory = factory;
	}

	public Car orderCar() {
		return factory.createCar();
	}
}

抽象工厂方法代码示例:

public interface CarFactory {    // 工厂接口
	Car createcar();
	IntelligentDriving createIntelligentDriving();
}

public class XiaomiCarFactory implements CarFactory {    // 小米汽车工厂实现类
	public Car createCar() {
		return new XiaomiCar();
	}
	
	public IntelligentDriving createIntelligentDriving() {
		return new XiaomiIntelligentDriving();
	}
}

3、原型模式 

定义:通过复制一个现有对象来创建新对象,而不是通过new新的对象

应用场景:

  • 当需要创建对象的代价非常高时:需要初始化很多数据的大型对象
  • 创建大量相似对象时:在游戏开发中,可能需要大量相似的敌人或道具

 代码示例:

public class Car implements Cloneable {
	public Car() {}

	public Car clone() throws CloneNotSupportedException {
		return (Car) super.clone();
	}
}

 4、建造者模式

定义:逐步构建复杂对象,其实就是Lombok中的@Builder,说白了像制作汉堡,首先选择面包,再选择肉类,最后加上配料,得到一个完整的汉堡

应用场景:

  • 对象的创建过程非常复杂:创建带有CPU、内存、硬盘等的主机类

代码示例:

public class Burger {    // 汉堡类
	private String bread;
	private String meat;


	private Burger(Builder builder) {
		this.bread = builder.bread;
		this.meat = builder.meat;

	}

	public static class Builder {    // 静态构建类
		private String bread;
		private String meat;


		public Builder setBread(String bread) {
			this.bread = bread;
			return this;
		}

		public Builder setMeat(String meat) {
			this.meat = meat;
			return this;
		}


		public Burger build() {
			return new Burger(this);
		}
	}

}

public static void main(String[] args) {    // 测试
	Burger burger = new Burger.Builder()    // 使用建造者模式创建一个汉堡
						.setBread("塔斯汀面包胚")
						.setMeat("碳烤十分熟牛肉")
						.build();
}

二、结构型模式 

1、代理模式

定义:为一个对象提供一个代理对象以控制对某个对象的访问,说白了就是租客和房东之间的中介

分类:

  • 静态代理:代理类在编译期就生成
  • 动态代理:代理类在运行时动态生成,分为JDK动态代理(需要实现接口)、CGLIB动态代理(无需实现接口)

应用场景:

  • 为对象提供一个代理对象来控制访问权限、进行缓存、延迟初始化等

静态代理代码示例:

public interface SellHouse {    // 被代理对象接口
	void sellHouse();
}

public class Landlord implements SellHouse {    // 被代理对象实现类
	public void sell() {
		System.out.println("房东卖房");
	}
}

public class ProxyPoint implements SellHouse {    // 代理类
	private Landlord landlord = new Landlord();
	public void sell() {
		System.out.println("我是中介,我想多收点钱");
		landlord.sell();
	}
}

 JDK提供的动态代理代码示例:

public class ProxyFactory {    // 代理工厂类
	private Landlord landlord = new Landlord();
	public SellHouse getProxyObject() {
		// 参数分别为:被代理类的类加载器、被代理对象实现的接口、代理要做的事(方法)
		SellHouse sellHouse = (SellHouse) Proxy.newProxyInstance(landlord.getClass().getClassLoader(),landlord.getClass().getInterfaces(),new InvocationHandler() {
					// 参数分别为:代理对象、调用接口方法的Method实例、调用接口方法传递的参数
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("我是中介,我想多收点钱");
						Object result = method.invoke(landlord, args);
						return result;
					}
				});
		return sellHouse;
	}
}

public static void main(String[] args) {	// 测试
	ProxyFactory factory = new ProxyFactory();
	SellHouse proxyObject = factory.getProxyObject();
	proxyObject.sell();
}

CGLIB动态代理代码示例:需要导包cglib.jar

public class SellHouse {    // 被代理方法
	public void sell() {
		System.out.println("卖房子");
	}
}

public class ProxyFactory implements MethodInterceptor {    // 代理工厂类
	private Landlord landlord = new Landlord();
	public Landlord getProxyObject() {
		Enhancer enhancer =new Enhancer();    // 类似JDK动态代理的Proxy类
		enhancer.setSuperclass(landlord.getClass());    // 设置父类字节码对象
		enhancer.setCallback(this);    // 设置回调函数
		Landlord obj = (Landlord) enhancer.create();
		return obj;
	}
	
	// 参数分别为:代理对象、调用被代理类方法的Method实例、调用方法传递的参数、用于调用被代理类方法的代理对象
	public Landlord intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		System.out.println("我是中介,我想多收点钱");
		Landlord result = (Landlord) methodProxy.invokeSuper(obj, args);
		return result;
	}
	
	public static void main(String[] args) {        
		ProxyFactory factory = new ProxyFactory();
		SellHouse proxyObject = factory.getProxyObject();
		proxyObject.sell();
	}
}

2、适配器模式

定义:让由于接口不兼容而不能一起工作的类能协同工作,说白了Usb插不进Typec接口,就需要Typec-Usb转换器作为中介连接二者

分类:

  • 类适配器:使用继承+实现接口组成适配器,违背聚合复用原则
  • 对象适配器:耦合更低

应用场景:

  • 将类的接口转换为另一个客户端能够使用的接口 

类适配器代码示例:

public interface Typec {    // Typec接口
	String typecTransmit();
}

public class TypecImpl implements Typec {    // Typec实现类
	private String data = "abc";
	public String typecTransmit() {
		return data;
	}
}

public interface Usb {    // USB接口
	String usbTransmit();
}

public class UsbImpl implements Usb {    // USB实现类
	private String data = "abc";
	public String usbTransmit() {
		return data;
	}
}

public class Computer {    // 主机类,需要兼容使用的类
	public String receive(Typec typec) {
		return typec.typecTransmit();
	}
}

public class TypecAdapterUsb extends UsbImpl implements Typec {    // 适配器类,让Computer能够调用Usb
	public String typecTransmit() {
		return usbTransmit();
	}
}

public static void main(String[] args) {    // 测试
	Computer computer = new Computer();
	TypecAdapterUsb adapter = new TypecAdapterUsb();
	String data = computer.receive(adapter));
}

对象适配器代码示例:

public class TypecAdapterUsb implements Typec {    // 适配器类
	private Usb usb;

	public TypecAdapterUsb(Usb usb) {
		this.usb = usb;
	}
	
	public String typecTransmit() {
		return usb.usbTransmit();
	}
}

public static void main(String[] args) {    // 测试
	Computer computer = new Computer();
	Usb usb = new UsbImpl();
	TypecAdapterUsb adapter = new TypecAdapterUsb(usb);
	String data = computer.receive(adapter));
}

3、装饰者模式

定义:不改变对象源代码的情况下,动态地给对象加一些额外功能,说白了就像手机膜给手机屏幕加了保护功能

应用场景:

  • 某些额外小功能没必要通过继承等方式实现 

代码示例:

public interface Phone {    // 手机接口
	String getparts();
}

public class BasePhone implements Phone {    // 手机类
	public String getparts() {
		return "本体手机";
	}
}

public class ProtectiveFilmDecorator implements Phone {    // 保护膜装饰器类
	private Phone phone;

	public ProtectiveFilmDecorator(Phone phone) {
		this.phone = phone;
	}

	public String getparts() {
		return phone.getDescription() + ", 手机膜";
	}
}

public static void main(String[] args) {
	Phone phone = new Phone();
	Phone protectiveFilmPhone = new ProtectiveFilmDecorator(phone);
	String parts = protectiveFilmPhone.getparts();    // 输出为<本体手机,手机膜>
}

4、桥接模式

定义:抽象与实现分离,使它们可以独立变化,说白了就像汽车上的发动机,当你需要安装不同的发动机不必要修改整个汽车

应用场景:

  • 需要在不修改原有代码的情况下,方便地更换、扩展功能时 

代码示例:

public interface Engine {    // 发动机接口
	void start();
}

public class PetrolEngine implements Engine {    // 汽油发动机实现类
	public void start() {
		System.out.println("汽油发动机,启动!");
	}
}

public class DieselEngine implements Engine {    // 柴油发动机实现类
	public void start() {
		System.out.println("柴油发动机,启动!");
	}
}

public abstract class Car {    // 汽车抽象类
	private Engine engine;

	private Car(Engine engine) {
		this.engine = engine;
	}
	abstract void drive();
}

public class SUV extends Car {    // SUV汽车类
	public SUV(Engine engine) {
		super(engine);
	}
	public void drive() {
		engine.start();
	}
}

public static void main(String[] args) {
	Car suv = new SUV(new PetrolEngine());    // 传入需要的发动机类,后续需要修改只需要创建新的实现类
}   

5、外观模式 

定义:提供一个简化的接口来访问复杂的子系统,说白了像汽车你插入钥匙转一转就启动了,而不是说你先打开发动机、打开中控、打开灯光等一系列操作汽车才完全启动

应用场景:

  • 屏蔽了子系统组件,让客户感受不到子系统组件

 代码示例:

public class Engine {    // 发动机类
	void start() {
		System.out.println("发动机,启动!");
	}
}

public class CentralControl {    // 中控类
	void start() {
		System.out.println("中控,启动!");
	}
}

public class CarFacade {    // 汽车外观模式,提供drive()一键启动发动机和中控
	private Engine engine;
	private CentralControl cc;

	public CarFacade() {
		engine = new Engine();
		cc = new CentralControl();
	}

	public void drive() {
		engine.start();
		cc.start();
		System.out.println("汽车启动完毕,踩油门吧!");
	}
}

6、组合模式

定义:树状结构连接对象,说白了像部门以树状结构组织,可以整体管理,也可以管理其中的某个子节点

应用场景:

  • 需要用到树状结构连接多个对象:文件目录等

代码示例:

public interface Employee {    // 员工接口
	void showEmployeeInfo();
}

public class Developer implements Employee {    // 开发人员类
	private String name;

	public Developer(String name,) {
		this.name = name;
	}

	public void showEmployeeInfo() {
		System.out.println(name);
	}
}

public class Manager implements Employee {    // 经理人员类
	private String name;

	public Manager(String name, String id) {
		this.name = name;
	}

	public void showEmployeeInfo() {
		System.out.println(name);
	}
}

public class CompanyDirectory implements Employee {    // 公司目录类
	private List<Employee> employeeList = new ArrayList<>();

	public void addEmployee(Employee employee) {    // 增加员工方法
		employeeList.add(employee);
	}

	public void removeEmployee(Employee employee) {    // 删除员工方法
		employeeList.remove(employee);
	}

	public void showEmployeeInfo() {    // 遍历调用各个员工方法
		for (Employee emp : employeeList) {
			emp.showEmployeeInfo();
		}
	}
}

public static void main(String[] args) {
	Developer dev1 = new Developer("xiaoming", "001");
	Developer dev2 = new Developer("lihua", "002");
	
	Manager mgr1 = new Manager("xiaosong", "003");

	CompanyDirectory devDirectory = new CompanyDirectory();    // 开发部门
	devDirectory.addEmployee(dev1);
	devDirectory.addEmployee(dev2);

	CompanyDirectory mgrDirectory = new CompanyDirectory();    // 经理部门
	mgrDirectory.addEmployee(mgr1);

	CompanyDirectory companyDirectory = new CompanyDirectory();    // 公司总部门,将开发部门和经理部门纳入
	companyDirectory.addEmployee(devDirectory);
	companyDirectory.addEmployee(mgrDirectory);

	companyDirectory.showEmployeeInfo();
}

7、享元模式

定义:共享已经存在的对象

应用场景:

  • 存在大量一样的对象,可以通过共享对象来减少内存使用 

代码示例:

public interface Shape {    // 形状接口
	void draw();
}

public class Circle implements Shape {    // 圆实现类
	private String color;

	public Circle(String color) {
		this.color = color;
	}

	public void draw() {
		System.out.println("画" + color + "的圆");
	}
}

public class ShapeFactory {    // 形状工厂类
	private static final Map<String, Shape> circleMap = new HashMap<>();    // 通过Map保存对象,反复利用

	public static Shape getCircle(String color) {
		Circle circle = (Circle) circleMap.get(color);
		if (circle == null) {
			circle = new Circle(color);
			circleMap.put(color, circle);
		}
		return circle;
	}
}

三、行为型模式

1、模板方法模式

定义:固定流程不变,但其中的某些步骤可以根据不同情况由不同子类来实现

应用场景:

  • 整体步骤固定,但存在个别部分易变,可以抽离出来供子类实现

代码示例:

public abstract class CookingTemplate {    // 做饭模板抽象类,将加配料方法抽象出来(因为可以加不同的配料)
	public final void cook() {    // final防止恶意操作
		prepareIngredients();
		startCooking();
	}

	abstract void prepareIngredients();    // 加配料可能不一样所以抽象,让子类实现

	private void startCooking() {
		System.out.println("生火起锅");
	}
}

public class NoodlesCooking extends CookingTemplate {    // 面条子类
	protected void prepareIngredients() {
		System.out.println("面条要加的配料");
	}
}

public static void main(String[] args) {    // 测试
	CookingTemplate noodlesCooking = new NoodlesCooking();
	noodlesCooking.cook();
}

2、策略模式

定义:将一系列算法封装起来,并且使它们可互相替换,说白了有几种不同的方法来解决同一个问题,可以在运行时根据需要选择其中一种方法

应用场景:

  • 类在算法或行为上有不同的场景,如支付功能,可以使用支付宝、微信等 

代码示例:

public interface PaymentStrategy {    // 支付策略接口
	void pay(int amount);
}

public class ZfbPayment implements PaymentStrategy {    // 支付宝支付类
	public void pay(int amount) {
		System.out.println("使用支付宝支付" + amount + "元");
	}
}

public class WxPayment implements PaymentStrategy {    // 微信支付类
	public void pay(int amount) {
		System.out.println("使用微信支付" + amount + "元");
	}
}

public class ShoppingPayment {    // 购物支付环境类
	private PaymentStrategy paymentStrategy;

	public ShoppingPayment(PaymentStrategy paymentStrategy) {
		this.paymentStrategy = paymentStrategy;
	}

	public void checkout(int amount) {
		paymentStrategy.pay(amount);
	}
}

public static void main(String[] args) {    // 测试
	ShoppingPayment pay = new ShoppingPayment(new ZfbPayment());
	pay.checkout(100);

}

3、命令模式

定义:使发出请求的对象和执行请求的对象之间通过命令对象进行沟通,说白了遥控器可以发出增大音量、切换频道等命令,电视收到后就执行

应用场景:

  • 需要将请求对象和执行对象解耦 

代码示例:

public interface Command {    // 命令接口,所有命令都需要实现该接口
	void execute();
}

public class Audio {    // 电视音频控制器类
	public void up() {
		System.out.println("音量调大");
	}
}

public class AudioCommand implements Command {    // 音频命令类
	private Audio audio;

	public LightOnCommand(Audio audio) {
		this.audio = audio;
	}

	public void execute() {
		audio.up();
	}
}

public class RemoteControl {    // 遥控器调用类
	private Command command;

	public void setCommand(Command command) {
		this.command = command;
	}

	public void upAudio() {
		command.execute();
	}
}

public static void main(String[] args) {    // 测试
	Audio audio = new Audio();
	Command audioUp = new LightOnCommand(Audio);

	RemoteControl remote = new RemoteControl();
	remote.setCommand(lightOn);
	remote.upAudio();
}

4、责任链模式

定义:创建一个接收对象的链,请求来的时候,这些接收对象依次接收,能处理就处理,不能处理就传给下一个接收对象,直到无对象处理失败

应用场景:

  • 有多个对象可以处理同一个请求,但具体处理者在运行时确定

代码示例:

public abstract class Handler {    // 接收对象抽象父类
	protected Handler next;

	public void setNextHandler(Handler next) {
		this.next = next;
	}

	public void handleRequest(String request) {
		if (next != null) {
			next.handleRequest(request);
		} else {
			System.out.println("没对象可以处理!");        
		}
	}
}

public class LevelOneHandler extends Handler {    // 1级接收对象子类
	public void handleRequest(String request) {
		if (request.equals("level-1")) {
			System.out.println("我来处理...");
		} else {
			super.handleRequest(request);
		}
	}
}

public class LevelTwoHandler extends Handler {    // 2级接收对象子类
	public void handleRequest(String request) {
		if (request.equals("level-2")) {
			System.out.println("我来处理...");
		} else {
			super.handleRequest(request);
		}
	}
}

public static void main(String[] args) {    // 测试
	Handler level1 = new LevelOneHandler();
	Handler level2 = new LevelTwoHandler();

	level1.setNextHandler(level2);

	basic.handleRequest("level-1");
	basic.handleRequest("level-2");
	basic.handleRequest("level-3");    // 无对象处理
}

5、状态模式

定义:让对象在不同状态下有不同的行为

应用场景

  • 对象的行为依赖于状态,并且在运行时可以改变状态,如电梯类,上升状态、下降状态 

代码示例:

public interface ElevatorState {    // 电梯状态接口
	void pressButton();
}

public class MovingUpState implements ElevatorState {    // 电梯上升状态实现类
	public void pressButton() {
		System.out.println("电梯正在上升...");
	}
}

public class MovingDownState implements ElevatorState {    // 电梯下降实现类
	public void pressButton() {
		System.out.println("电梯正在下降...");
	}
}

public class Elevator {    // 状态管理环境类
	private ElevatorState state;

	public void setState(ElevatorState state) {    // 改变状态
		this.state = state;
	}

	public void pressButton() {    // 根据状态执行不同方法
		state.pressButton();
	}
}

public static void main(String[] args) {    // 测试
	Elevator elevator = new Elevator();

	elevator.setState(new MovingUpState());
	elevator.pressButton();

	elevator.setState(new MovingDownState());
	elevator.pressButton();
}

6、观察者模式(发布-订阅模式)

定义:多个观察者对象监听一个主题对象,主题对象状态变化,会通知所有的观察者对象行动

应用场景:

  • 多个对象需要观察某个对象的状态变化,如消息推送
  • 广播系统

代码示例:

public interface Observer {    // 观察者对象接口
	void update(String message);
}

public class Subscriber implements Observer {    // 观察者对象实现类
	public Subscriber() {}

	public void update(String message) {
		System.out.println("接收消息:" + message);
	}
}

public interface Subject {    // 主题对象接口
	void registerObserver(Observer observer);
	void removeObserver(Observer observer);
	void notifyObservers(String message);
}

public class WeChatPublicAccount implements Subject {    // 主题对象实现类
	private List<Observer> observers;

	public WeChatPublicAccount() {
		observers = new ArrayList<>();
	}

	public void registerObserver(Observer observer) {
		observers.add(observer);
	}

	public void removeObserver(Observer observer) {
		observers.remove(observer);
	}

	public void notifyObservers(String message) {        
		for (Observer observer : observers) {
			observer.update(message);
		}
	}
}

public static void main(String[] args) {    // 测试
	WeChatPublicAccount account = new WeChatPublicAccount();
	Observer user1 = new Subscriber();
	Observer user2 = new Subscriber();

	account.registerObserver(user1);
	account.registerObserver(user2);
	account.notifyObservers("军中无细盐");
}

7、中介者模式

定义:用一个中介对象来封装一系列对象之间的交互,中介对象使各个对象不需要显示地相互引用

应用场景:

  • 通过引入一个中介者对象来简化各对象之间的交互,如聊天室,所有对象通过服务器类来发送和接收消息 

代码示例:

public interface Mediator {    // 中介对象接口
	void sendMessage(String message, User user);
}

public class ChatMediator implements Mediator {    // 聊天中介对象实现类
	private List<User> userList;

	public ChatMediator() {
		userList = new ArrayList<>();
	}

	public void addUser(User user) {
		userList.add(user);
	}

	public void sendMessage(String message, User user) {
		for (User u : userList) {
			if (u != user) {
				u.receiveMessage(message);
			}
		}
	}
}        

public abstract class User {    // 用户抽象类
	private Mediator mediator;

	public User(Mediator mediator) {
		this.mediator = mediator;
	}

	public abstract void sendMessage(String message);
	public abstract void receiveMessage(String message);
}        

public class UserBasic extends User {    // 用户具体类
	public UserBasic(Mediator mediator) {
		super(mediator);
	}

	public void sendMessage(String message) {
		System.out.println("发送消息: " + message);
		mediator.sendMessage(message, this);
	}

	public void receiveMessage(String message) {
		System.out.println("接收消息: " + message);
	}
}

public static void main(String[] args) {    // 测试
	Mediator mediator = new ChatMediator();
	Colleague user1 = new User(mediator);
	Colleague user2 = new User(mediator);

	((ChatMediator) mediator).addColleague(user1);
	((ChatMediator) mediator).addColleague(user2);

	user1.sendMessage("军中无细盐");
}

8、迭代器模式

定义:提供一种方法顺序访问聚合对象中的各个元素,而不暴露其内部

应用场景:

  • 在不暴露集合内部结构的情况下进行遍历,如Java集合类很多使用到

代码示例:

public interface Iterator {    // 迭代器接口
	boolean hasNext();
	Object next();
}

public class BookIterator implements Iterator {    // 迭代器实现类
	private List<String> books;
	private int position;

	public BookIterator(List<String> books) {
		this.books = books;
		this.position = 0;
	}

	public boolean hasNext() {
		return position < books.size();
	}

	public Object next() {
		if (this.hasNext()) {
			return books.get(position++);
		}
		return null;
	}
}        

public class BookCollection {    // 集合类
	private List<String> books;

	public BookCollection() {
		books = new ArrayList<>();
	}

	public void addBook(String book) {
		books.add(book);
	}

	public Iterator createIterator() {
		return new BookIterator(books);
	}
}

public static void main(String[] args) {    // 测试
	BookCollection collection = new BookCollection();
	collection.addBook("Book 1");
	collection.addBook("Book 2");

	Iterator iterator = collection.createIterator();
	while (iterator.hasNext()) {
		System.out.println(iterator.next());
	}
}

9、访问者模式

定义:不改变对象结构的情况下,定义新的操作,说白了就像导游可以给你讲解不同的景点知识,但景点本身不变

应用场景:

  • 需要对对象进行许多不同且不相关的操作

代码示例:

public interface TouristSpot {    // 景点接口
	void accept(TourGuide guide);
}        

public class Museum implements TouristSpot {    // 博物馆景点实现类
	public void accept(TourGuide guide) {
		guide.visit(this);
	}
}

public interface TourGuide {    // 导游接口
	void visit(Museum museum);
}

public class HistoricalTourGuide implements TourGuide {    // 导游介绍景点历史实现类
	public void visit(Museum museum) {
		System.out.println("博物馆有这样的历史:巴拉巴拉");
	}
}

public class CulturalTourGuide implements TourGuide {    // 导游介绍景点文化实现类
	public void visit(Museum museum) {
		System.out.println("博物馆有这样的文化:巴拉巴拉");
	}
}

public static void main(String[] args) {    // 测试
	TouristSpot spot = new Museum()
	
	TourGuide historicalGuide = new HistoricalTourGuide();
	spot.accept(historicalGuide);

	TourGuide culturalGuide = new CulturalTourGuide();
	spot.accept(culturalGuide);
}

10、备忘录模式

定义:在不破坏封装的前提下,保存对象内部状态,以便日后可以将对象恢复到保存的状态,说白了就像保存游戏进度,打输了就回档

分类:

  • “白箱”:备忘录的内部状态对外部是可见
  • ”黑箱“:备忘录的内部状态对外部是封闭

应用场景:

  • 需要保存和恢复对象的状态 

白箱代码示例:

public class Memento {    // 备忘录类
	public String state;    // 开放

	public Memento(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}
}        

public class Originator {    // 需要保存的对象类
	private String state;

	public void setState(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}

	public Memento saveStateToMemento() {
		return new Memento(state);
	}

	public void getStateFromMemento(Memento memento) {
		state = memento.getState();
	}
}
 
public class Caretaker {    // 备忘录管理类
	private List<Memento> mementoList = new ArrayList<>();

	public void add(Memento state) {
		mementoList.add(state);
	}

	public Memento get(int index) {
		return mementoList.get(index);
	}
}        

public static void main(String[] args) {    // 测试
	Originator originator = new Originator();
	originator.setState("State1");
	
	Caretaker caretaker = new Caretaker();
	caretaker.add(originator.saveStateToMemento());
	
	originator.setState("State666");

	originator.getStateFromMemento(caretaker.get(0));
	System.out.println("恢复数据: " + originator.getState());
}

黑箱代码示例:

public class Originator {    // 需要保存的对象类
	private String state;

	public void setState(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}

	public Memento saveStateToMemento() {
		return new Memento(state);
	}

	public void getStateFromMemento(Memento memento) {
		state = memento.getState();
	}

	private static class Memento {    // 黑箱备忘录类,内部状态只有Originator可以访问    
		private final String state;    // 状态是私有的
		 
		private Memento(String state) {    // 构造方法是私有的,只有Originator可以创建Memento
			this.state = state;
		}

		private String getState() {
			return state;
		}
	}
}

public class Caretaker {    // 备忘录管理类
	private List<Originator.Memento> mementoList = new ArrayList<>();

	public void add(Originator.Memento memento) {
		mementoList.add(memento);
	}

	public Originator.Memento get(int index) {
		return mementoList.get(index);
	}
}

public static void main(String[] args) {    // 测试
	Originator originator = new Originator();
	originator.setState("State1");

	Caretaker caretaker = new Caretaker();
	caretaker.add(originator.saveStateToMemento());
	
	originator.setState("State666");

	originator.getStateFromMemento(caretaker.get(0));
	System.out.println("恢复数据: " + originator.getState());
}

11、解释器模式

定义:把特定语法规则翻译成可执行的指令

应用场景:

  • 语法较简单且需要频繁对表达式求值 

代码示例:

public interface Expression {    // 表达式接口
	int interpret();
}        

public class NumberExpression implements Expression {    // 终结符表达式类
	private int number;

	public NumberExpression(int number) {
		this.number = number;
	}

	public int interpret() {
		return number;
	}
}        

public class AddExpression implements Expression {    // 非终结符表达式类
	private Expression leftExpression;
	private Expression rightExpression;

	public AddExpression(Expression leftExpression, Expression rightExpression) {
		this.leftExpression = leftExpression;
		this.rightExpression = rightExpression;
	}

	public int interpret() {
		return leftExpression.interpret() + rightExpression.interpret();
	}
}        

public static void main(String[] args) {    // 测试
	Expression left = new NumberExpression(3);
	Expression right = new NumberExpression(5);
	Expression add = new AddExpression(left, right);
	System.out.println("3 + 5 = " + add.interpret());
}

 

 

 

java设计模式大体上分为三大类: 创建型模式(5):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。 行为型模式(11):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 设计模式遵循的原则有6个: 1、开闭原则(Open Close Principle)   对扩展开放,对修改关闭。 2、里氏代换原则(Liskov Substitution Principle)   只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。 3、依赖倒转原则(Dependence Inversion Principle)   这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle)   使用多个隔离的借口来降低耦合度。 5、迪米特法则(最少知道原则)(Demeter Principle)   一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle)   原则是尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值