视频:https://www.bilibili.com/video/BV1Np4y1z7BU?p=1&vd_source=fc7fa697b97f292319c5b0cde4755484
代码:https://gitee.com/wangzai6/design_pattern.git
1.java设计模式7大原则
1.单一职责:
2.接口隔离原则
1.图解:
2.实现:
1.三个接口
2.B类实现1,2接口
3.D类实现1,3接口
4.A类通过使用Interface1,2 依赖使用B类,只会用到1,2,3方法
5.C类通过使用Interface1,3依赖使用D类,只会用到1,4,5方法
6.A类通过实例化B类使用B中的方法
7.C类通过实例化D类使用D中的方法
3.依赖倒转原则
1.原来使用
2.改进
4.里氏替换原则
5.开闭原则(ocp原则)
6.迪米特法则
7.合成复用原则
2.设计模式分类
1.创建型模式
1.单例模式
1.饿汉式:类加载就会导致该实例对象被创建
1.饿汉式(静态变量方式)
package com.hejiawang.pattern.singleton.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 10:54
**/
//饿汉式:静态成员变量
public class Singleton {
// 1.私有构造方法
private Singleton(){
}
// 2.在奔雷中创建本类对象
private static Singleton instance = new Singleton();
// 3.提供一个公共的访问方式,让外界获取改对象
public static Singleton getInstance(){
return instance;
}
}
查看测试结果
2.饿汉式(静态代码块)
package com.hejiawang.pattern.singleton.demo2;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//饿汉式:静态代码块
public class Singleton {
// 私有构造方法
private Singleton(){}
// 声明Singleton类型的变量
private static Singleton instance; //null
// 在静态代码块中进行赋值
static {
instance = new Singleton();
}
// 对外提供获取该类对象的方法
public static Singleton getInstance(){
return instance;
}
}
查看测试结果
说明
2.懒汉式:类加载不会导致该实例对象被创建,而是首次使用该对象时才会创建
1.懒汉式(线程不安全)
如果2个线程同时进入判断 条件,则创建的实例不删单例
package com.hejiawang.pattern.singleton.demo3;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式
public class Singleton {
// 私有构造方法
private Singleton(){}
// 声明Singleton类型的变量
private static Singleton instance; //null
// 对外提供获取该类对象的方法
public static Singleton getInstance(){
// 判断instance是否为null,如果为null,说明还没有创建爱你Singleton类的对象
// 如果没有,创建一个并返回,如果有直接返回
if(instance == null){
// 线程1等待,线程2获取cpu的执行权,也会进入改判断里面,所以可能创建多个实例
instance = new Singleton();
}
return instance;
}
}
2.懒汉式(线程安全)
在拿实例方法上面加上synchronized锁,线程即安全
package com.hejiawang.pattern.singleton.demo3;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式
public class Singleton {
// 私有构造方法
private Singleton(){}
// 声明Singleton类型的变量
private static Singleton instance; //null
// 对外提供获取该类对象的方法
public static synchronized Singleton getInstance(){
// 判断instance是否为null,如果为null,说明还没有创建Singleton类的对象
// 如果没有,创建一个并返回,如果有直接返回
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
3.懒汉式(双重检查锁方式)
对于getInstance()方法来说,绝大部分都是读操作,读操作是线程安全的,所以没必要让每个线程必须持有锁才调用方法,我们需要调整加锁的时机,即双重检查锁模式
package com.hejiawang.pattern.singleton.demo4;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式:双重检查锁方式
public class Singleton {
// 私有构造方法
private Singleton(){}
// 声明Singleton类型的变量
private static Singleton instance; //null
// 对外提供获取该类对象的方法
public static Singleton getInstance(){
// 第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
if(instance == null){
synchronized (Singleton.class){
// 第二次判断
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4.使用volitale保证变量有序性和可见性
双重检查锁模式是一种非常好的单例实现模式,解决了单例,性能,线程安全问题,看上去完美无缺,其实存在许多问题,在多线程的情况下,可能出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作。要解决双重检查锁模式带来的空指针异常的问题,只需要使用volatile关键字,volatile关键字可以保证可见性和有序性
package com.hejiawang.pattern.singleton.demo4;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式:双重检查锁方式(使用volatile保证可见性和有序性)
public class Singleton {
// 私有构造方法
private Singleton(){}
// 声明Singleton类型的变量
private static volatile Singleton instance; //null
// 对外提供获取该类对象的方法
public static Singleton getInstance(){
// 第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
if(instance == null){
synchronized (Singleton.class){
// 第二次判断
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
5.懒汉式方式(静态内部类方式)
第一次加载Singleton类时不会去初始化INSTANCE,只有第一次调用getinstance,虚拟机加载SingletonHolder并初始化INSTANCE,这样不仅确保线程安全,也能保证Singleton类的唯一性,这种方式保证了多线程下的安全,并且没有任何性能影响和空间浪费
静态内部类单例模式中实例有内部类创建,由于JVM在加载外部类的过程中,是不会加载静态内部类,只有内部类的属性/方法被调用时候才加载,并初始化其静态属性,静态属性由于被static修饰,保证只被实例化一次,并严格保证实例化顺序
package com.hejiawang.pattern.singleton.demo5;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式:静态内部类方式
public class Singleton {
// 私有构造方法
private Singleton(){}
// 定义一个静态内部类
private static class SingletonHolder{
// 在内部类中声明并初始化外部类的对象
private static final Singleton INSTANCE = new Singleton();
}
// 提供公共的访问方式
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
3.枚举方式属于饿汉方式
使用枚举类实现单例模式是极利推荐的,因为枚举类型是线程安全的,并且只会加载一次
package com.hejiawang.pattern.singleton.demo6;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//枚举实现方式 属于饿汉方式
public enum Singleton {
INSTANCE;
}
查看检查结果
4.通过序列化和反序列化可破坏单例模式及解决办法
反序列化破坏单例Demo
package com.hejiawang.pattern.singleton.demo7;
import com.hejiawang.pattern.singleton.demo7.Singleton;
import java.io.*;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:06
**/
//测试使用反射破坏单例模式
public class Client {
public static void main(String[] args) throws Exception {
// writeObject2File();
readObjectFromFile();
readObjectFromFile();
}
// 从文件中读取数据(对象)
public static void readObjectFromFile() throws IOException, ClassNotFoundException {
// 1.创建爱你对象输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/hejiawang/IdeaProjects/gitee/a.txt"));
// 2.读取对象
Singleton instance = (Singleton) ois.readObject();
System.out.println(instance);
ois.close();
}
// 向文件中写数据(对象)
public static void writeObject2File() throws Exception {
// 1.获取Singleton对象
Singleton instance = Singleton.getInstance();
// 2.创建对象输出流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/hejiawang/IdeaProjects/gitee/a.txt"));
// 3.写对象
oos.writeObject(instance);
oos.close();
}
}
检测结果:
两个地址不一致,两次反序列化的结果不是同一个地址
解决办法:
对象加上readResolve()方法返回对象即可,
public class Singleton implements Serializable {
// 私有构造方法
private Singleton(){}
// 定义一个静态内部类
private static class SingletonHolder{
// 在内部类中声明并初始化外部类的对象
private static final Singleton INSTANCE = new Singleton();
}
// 提供公共的访问方式
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
// 当进行反序列化时,自动调用改方法,将该方法的返回值直接返回
public Object readResolve(){
return SingletonHolder.INSTANCE;
}
}
重新序列化到文件中,并且重新执行读取对象打印对象内存地址,如下任然是单例
源码中会直接返回readResolve()方法的结果
5.通过反射破坏单例模式及解决办法
反射破坏单例Demo
package com.hejiawang.pattern.singleton.demo8;
import java.io.*;
import java.lang.reflect.Constructor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:06
**/
//测试使用反射破坏单例模式
public class Client {
public static void main(String[] args) throws Exception {
// 1.获取Singleton的字节码对象
Class clazz = Singleton.class;
// 2.获取无参构造方法对象
Constructor cons = clazz.getDeclaredConstructor();
// 3.取消访问检查
cons.setAccessible(true);
// 4.创建Singleton对象
Singleton s1 = (Singleton) cons.newInstance();
Singleton s2 = (Singleton) cons.newInstance();
System.out.println(s1 == s2); //如果返回的是true,说明并没有破坏单例模式,如果是false,说明破坏了单例模式
}
}
结果
解决办法
在反射使用的无参构造方法中加入static flag 判断是第几次调无参构造方法。
package com.hejiawang.pattern.singleton.demo8;
import java.io.Serializable;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式:静态内部类方式
public class Singleton implements Serializable {
private static boolean flag = false;
// 私有构造方法
private Singleton(){
// 判断flag的值是否是true,如果是true,说明第一下访问,直接抛一个异常,如果是false的话,说明第一次访问,正常创建
if (flag){
throw new RuntimeException("不能创建多个对象");
}
// 将flag的值设置为true
flag = true;
}
// 定义一个静态内部类
private static class SingletonHolder{
// 在内部类中声明并初始化外部类的对象
private static final Singleton INSTANCE = new Singleton();
}
// 提供公共的访问方式
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
第二次利用反射初始化对象抛出运行时异常
6.JDK中单例设计模式的Demo
jdk中的源代码,饿汉式单例
RuntimeDemo
package com.hejiawang.pattern.singleton.demo9;
import jdk.internal.util.xml.impl.Input;
import org.omg.SendingContext.RunTime;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 11:03
**/
//懒汉式:静态内部类方式
public class RuntimeDemo implements Serializable {
public static void main(String[] args) throws IOException {
// 获取Runtime类的对象
Runtime runtime = Runtime.getRuntime();
// 调用runtime的方法exec,参数是一个命令
Process process = runtime.exec("ifconfig");
// 调用process对象的获取输入流的方法
InputStream is = process.getInputStream();
byte[] arr = new byte[1024 * 1024 * 100];
// 读取数据
int len = is.read(arr); //返回读取到的字节的个数
// 将字节数组转换为字符串输出到控制台
System.out.println(new String(arr,0,len,"GBK"));
}
}
即可在输出台看到命令打印的信息
2.工厂模式
工厂模式最大优点:解耦
1.简单工厂模式
Coffee
package com.hejiawang.pattern.factory.simple_factiory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 16:59
**/
public abstract class Coffee {
public abstract String getName();
// 加糖
public void addsugar(){
System.out.println("加糖");
}
// 加奶
public void addMilk(){
System.out.println("加奶");
}
}
LatteCoffee
package com.hejiawang.pattern.factory.simple_factiory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class LatteCoffee extends Coffee {
@Override
public String getName() {
return "拿铁咖啡";
}
}
AmericanCoffee
package com.hejiawang.pattern.factory.simple_factiory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:05
**/
public class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
SimpleCoffeeFactory
package com.hejiawang.pattern.factory.simple_factiory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:20
**/
public class SimpleCoffeeFactory {
public Coffee createCoffee(String type){
Coffee coffee = null;
if("american".equals(type)){
coffee = new AmericanCoffee();
} else if ("latte".equals(type)){
coffee = new LatteCoffee();
} else{
throw new RuntimeException("对不起,您所点的咖啡没有");
}
return coffee;
}
}
CoffeeStore
package com.hejiawang.pattern.factory.simple_factiory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class CoffeeStore {
public Coffee orderCoffee(String type){
SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
// 调用生产咖啡的方法
Coffee coffee = factory.createCoffee(type);
// 加配料
coffee.addMilk();
coffee.addsugar();
return coffee;
}
}
2.工厂方法模式
Coffee
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 16:59
**/
public abstract class Coffee {
public abstract String getName();
// 加糖
public void addsugar(){
System.out.println("加糖");
}
// 加奶
public void addMilk(){
System.out.println("加奶");
}
}
LatteCoffee
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class LatteCoffee extends Coffee {
@Override
public String getName() {
return "拿铁咖啡";
}
}
AmericanCoffee
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:05
**/
public class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
CoffeeFactory
package com.hejiawang.pattern.factory.factory_method;
//抽象工厂
public interface CoffeeFactory {
// 创建咖啡对象的方法
Coffee createCoffee();
}
LatteCoffeeFactory
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:48
**/
public class LatteCoffeeFactory implements CoffeeFactory {
public Coffee createCoffee() {
return new LatteCoffee();
}
}
AmericanCoffeeFactory
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:44
**/
public class AmericanCoffeeFactory implements CoffeeFactory{
public Coffee createCoffee() {
return new AmericanCoffee();
}
}
CoffeeStore
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class CoffeeStore {
private CoffeeFactory factory;
public void setFactory(CoffeeFactory factory){
this.factory = factory;
}
public Coffee orderCoffee(){
Coffee coffee = factory.createCoffee();
// 加配料
coffee.addsugar();
coffee.addMilk();
return coffee;
}
}
Client
package com.hejiawang.pattern.factory.factory_method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:25
**/
public class Client {
public static void main(String[] args) {
// 创建咖啡对象
CoffeeStore store = new CoffeeStore();
// 创建对象
// CoffeeFactory factory = new AmericanCoffeeFactory();
CoffeeFactory factory = new LatteCoffeeFactory();
store.setFactory(factory);
Coffee coffee = store.orderCoffee();
System.out.println(coffee.getName());
}
}
3.抽象工厂模式
Coffee
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 16:59
**/
public abstract class Coffee {
public abstract String getName();
// 加糖
public void addsugar(){
System.out.println("加糖");
}
// 加奶
public void addMilk(){
System.out.println("加奶");
}
}
LatteCoffee
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class LatteCoffee extends Coffee {
@Override
public String getName() {
return "拿铁咖啡";
}
}
AmericanCoffee
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:05
**/
public class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
Dessert
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:10
**/
public abstract class Dessert {
public abstract void show ();
}
MatchMousse
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:12
**/
public class MatchMousse extends Dessert {
@Override
public void show() {
System.out.println("抹茶慕斯");
}
}
Trimisu
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:11
**/
public class Trimisu extends Dessert{
@Override
public void show(){
System.out.println("提拉米苏");
}
}
DessertFactory
package com.hejiawang.pattern.factory.abstract_factory;
public interface DessertFactory {
// 生产咖啡的功能
Coffee createCoffee();
// 生产甜品的功能
Dessert createDessert();
}
ItalyDessertFactory
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:17
**/
public class ItalyDessertFactory implements DessertFactory{
public Coffee createCoffee() {
return new LatteCoffee();
}
public Dessert createDessert() {
return new Trimisu();
}
}
AmericanDessertFactory
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:14
**/
public class AmericanDessertFactory implements DessertFactory {
public Coffee createCoffee() {
return new AmericanCoffee();
}
public Dessert createDessert() {
return new MatchMousse();
}
}
Client
package com.hejiawang.pattern.factory.abstract_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:17
**/
public class Client {
public static void main(String[] args) {
// ItalyDessertFactory factory = new ItalyDessertFactory();
AmericanDessertFactory factory = new AmericanDessertFactory();
Coffee coffee = factory.createCoffee();
Dessert dessert = factory.createDessert();
System.out.println(coffee.getName());
dessert.show();
}
}
4.模式扩展(配置文件+工厂模式)
1.添加配置文件
american=com.hejiawang.pattern.factory.config_factory.AmericanCoffee
latte=com.hejiawang.pattern.factory.config_factory.LatteCoffee
2.代码演示
Coffee
package com.hejiawang.pattern.factory.config_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 16:59
**/
public abstract class Coffee {
public abstract String getName();
// 加糖
public void addsugar(){
System.out.println("加糖");
}
// 加奶
public void addMilk(){
System.out.println("加奶");
}
}
LatteCoffee
package com.hejiawang.pattern.factory.config_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:06
**/
public class LatteCoffee extends Coffee {
@Override
public String getName() {
return "拿铁咖啡";
}
}
AmericanCoffee
package com.hejiawang.pattern.factory.config_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-11 17:05
**/
public class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
CoffeeFactory加载配置文件,根据入参通过反射机制加载初始化需要创建的类
package com.hejiawang.pattern.factory.config_factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:36
**/
public class CoffeeFactory {
// 加载配置文件,获取配置文件中配置的全类名,并创建该类的对象进行存储
// 1.定义容器对象存储咖啡对象
private static HashMap<String,Coffee> map = new HashMap<String, Coffee>();
// 2.加载配置文件
static{
// 2.1创建Properties对象
Properties properties = new Properties();
// 2.2调用p对象中deload方法进行配置文件的加载
InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
properties.load(is);
Set<Object> keys = properties.keySet();
for (Object key: keys){
String className = properties.getProperty((String) key);
// 通过反射技术创建对象
Class clazz = Class.forName(className);
Coffee coffee = (Coffee) clazz.newInstance();
//将名称和对象存储到容器中
map.put((String)key,coffee);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Coffee createCoffee(String name){
return map.get(name);
}
}
Client
package com.hejiawang.pattern.factory.config_factory;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 10:47
**/
public class Client {
public static void main(String[] args) {
Coffee american = CoffeeFactory.createCoffee("american");
System.out.println(american.getName());
System.out.println("============");
Coffee latte = CoffeeFactory.createCoffee("latte");
System.out.println(latte.getName());
}
}
检测结果
5.jdk源码解析-Collection.iterator方法
3.原型模式
1.简单的原型模式演示
浅克隆和深克隆
原型模式Demo
Realizetype
package com.hejiawang.pattern.prototype.demo;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-13 14:01
**/
public class Realizetype implements Cloneable{
public Realizetype(){
System.out.println("具体的原型对象创建完成!");
}
@Override
protected Realizetype clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (Realizetype) super.clone();
}
}
Client
package com.hejiawang.pattern.prototype.demo;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:18
**/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
// 创建一个原型类对象
Realizetype realizetype = new Realizetype();
// 调用Realizetype类中的clone方法进行对象的克隆
Realizetype clone =realizetype.clone();
System.out.println("原型对象和克隆出来的是否是同一个对象?"+(realizetype == clone));
}
}
打印结果
2.原型对象使用Demo(浅克隆)
Citation
package com.hejiawang.pattern.prototype.test;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:28
**/
public class Citation implements Cloneable {
// 三好学生的姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected void show() {
System.out.println(name+"同学,被评为三好学生,特发此状,以兹鼓励");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
CitationTest
package com.hejiawang.pattern.prototype.test;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:32
**/
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
// 1.创建原型对象
Citation citation = new Citation();
// 2.克隆奖状对象
Citation citationClone = citation.clone();
citation.setName("飞鸽");
citationClone.setName("肥宅子");
// 3.调用show方法展示
citation.show();
citationClone.show();
}
}
打印结果
3.原型对象使用Demo(浅克隆)
浅克隆:创建新的对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所只想的对象的地址
Student
package com.hejiawang.pattern.prototype.test;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:38
**/
public class Student {
// 学生的姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
Citation
package com.hejiawang.pattern.prototype.test;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:28
**/
public class Citation implements Cloneable {
private Student student;
protected void show() {
System.out.println(student.getName()+"同学,被评为三好学生,特发此状,以兹鼓励");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
CitationTest
package com.hejiawang.pattern.prototype.test;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:32
**/
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
// 1.创建原型对象
Citation citation = new Citation();
// 创建学生对象
Student student = new Student();
student.setName("飞鸽");
citation.setStudent(student);
// 2.克隆奖状对象
Citation citationClone = citation.clone();
citationClone.getStudent().setName("肥宅子");
// 3.调用show方法展示
citation.show();
citationClone.show();
}
}
打印结果
4.使用序列化实现(深克隆)
注意序列化对象要实现Serializable接口
Student
package com.hejiawang.pattern.prototype.test1;
import java.io.Serializable;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:38
**/
public class Student implements Serializable {
// 学生的姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
Citation
package com.hejiawang.pattern.prototype.test1;
import java.io.Serializable;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:28
**/
public class Citation implements Cloneable, Serializable {
private Student student;
protected void show() {
System.out.println(student.getName()+"同学,被评为三好学生,特发此状,以兹鼓励");
}
@Override
protected Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
CitationTest
package com.hejiawang.pattern.prototype.test1;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 14:32
**/
public class CitationTest {
public static void main(String[] args) throws Exception {
// 1.创建原型对象
Citation citation = new Citation();
// 创建学生对象
Student student = new Student();
student.setName("飞鸽");
citation.setStudent(student);
// 创建对象输出流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/hejiawang/IdeaProjects/gitee/b.txt"));
// 写对象
oos.writeObject(citation);
// 释放资源
oos.close();
// 创建对象输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/hejiawang/IdeaProjects/gitee/b.txt"));
// 读取对象
Citation citation1 = (Citation) ois.readObject();
// 释放资源
ois.close();
Student student1 = citation1.getStudent();
student1.setName("肥宅子");
citation.show();
citation1.show();
}
}
打印结果
4.建造者模式
1.创建自行车案例
Bike
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:30
**/
public class Bike {
private String frame;//车架
private String seat;//车座
public String getFrame() {
return frame;
}
public void setFrame(String frame) {
this.frame = frame;
}
public String getSeat() {
return seat;
}
public void setSeat(String seat) {
this.seat = seat;
}
}
Builder
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:31
**/
public abstract class Builder {
// 声明Bike类型的变量,并进行赋值
protected Bike bike = new Bike();
public abstract void buildFrame();
public abstract void buildSeat();
public abstract Bike createBike();
}
MobileBuilder
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:34
**/
public class MobileBuilder extends Builder{
@Override
public void buildFrame() {
bike.setFrame("碳纤维车架");
}
@Override
public void buildSeat() {
bike.setSeat("真皮座驾");
}
@Override
public Bike createBike() {
return bike;
}
}
OfoBuilder
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:36
**/
public class OfoBuilder extends Builder{
@Override
public void buildFrame() {
bike.setFrame("铝合金车架");
}
@Override
public void buildSeat() {
bike.setSeat("橡胶车座");
}
@Override
public Bike createBike() {
return bike;
}
}
Director
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:37
**/
public class Director {
// 声明builder类型的变量
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
// 组装自行车的功能
public Bike construct(){
builder.buildFrame();
builder.buildSeat();
return builder.createBike();
}
}
Client
package com.hejiawang.pattern.factory.builder.demo1;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 16:41
**/
public class Client {
public static void main(String[] args) {
// 创建指挥者对象
Director director = new Director(new MobileBuilder());
// 让指挥者指挥组装自行车
Bike bike = director.construct();
System.out.println(bike.getFrame());
System.out.println(bike.getSeat());
}
}
打印结果
优化建造者模式
优缺点
使用场景
2.模式扩展
Phone对象类
package com.hejiawang.pattern.factory.builder.demo2;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-17 17:27
**/
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
// 私有构造方法
private Phone(Builder builder){
this.cpu = builder.cpu;
this.screen = builder.screen;
this.memory = builder.memory;
this.mainboard = builder.mainboard;
}
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Builder cpu(String cpu){
this.cpu = cpu;
return this;
}
public Builder screen(String screen){
this.screen = screen;
return this;
}
public Builder memory(String memory){
this.memory = memory;
return this;
}
public Builder mainboard(String mainboard){
this.mainboard = mainboard;
return this;
}
// 使用构建者创建Phone对象
public Phone build(){
return new Phone(this);
}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
Client测试类
package com.hejiawang.pattern.factory.builder.demo2;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 20:45
**/
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("m2")
.screen("小米屏幕")
.memory("金士顿")
.mainboard("华硕")
.build();
System.out.println(phone.toString());
}
}
打印结果
5.创建模式对比
2.结构型模式
1.代理模式
1.静态代理
SellTickets
package com.hejiawang.pattern.proxy.static_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:17
**/
public interface SellTickets {
void sell();
}
TrainStation
package com.hejiawang.pattern.proxy.static_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:18
**/
public class TrainStation implements SellTickets {
public void sell() {
System.out.println("火车站卖票");
}
}
ProxyPoint
package com.hejiawang.pattern.proxy.static_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:21
**/
//代售点类
public class ProxyPoint implements SellTickets {
// 声明火车站类对象
private TrainStation trainStation = new TrainStation();
public void sell() {
System.out.println("代售点收取一些服务费用");
trainStation.sell();
}
}
Client
package com.hejiawang.pattern.proxy.static_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:23
**/
public class Client {
public static void main(String[] args) {
// 创建代售点类对象
ProxyPoint proxyPoint = new ProxyPoint();
// 调用方法进行买票
proxyPoint.sell();
}
}
打印结果
2.动态代理
1.JDK动态代理
SellTickets
package com.hejiawang.pattern.proxy.jdk_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:17
**/
public interface SellTickets {
void sell();
}
TrainStation
package com.hejiawang.pattern.proxy.jdk_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:18
**/
public class TrainStation implements SellTickets {
public void sell() {
System.out.println("火车站卖票");
}
}
ProxyFactory
package com.hejiawang.pattern.proxy.jdk_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLOutput;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:29
**/
//获取代理对象的工厂类
//代理类也实现了对应的接口
public class ProxyFactory {
// 声明目标对象
private TrainStation station = new TrainStation();
// 获取代理对象的方法
public SellTickets getProxyObject() {
// 返回代理对象即可
/*
ClassLoader loader : 类加载器,用于加载代理类,可以通过目标对象获取类加载器
Class<?>[] interfaces : 代理类实现的接口的字节码对象
InvocationHandler h : 代理对象的调用处理程序
*/
SellTickets proxyInstance = (SellTickets) Proxy.newProxyInstance(station.getClass().getClassLoader(), station.getClass().getInterfaces(), new InvocationHandler() {
/*
* Object proxy : 代理对象和proxyInstance对象是同一个对象,在invoke方法中基本不用
* Method method : 对接口中的方法进行封装的method对象
* Object[] args : 调用方法的实际参数
*
* 返回值就是方法的返回值。
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("invoke方法执行了");
System.out.println("代售点收取一定的服务费用(jdk动态代理)");
// 执行目标对象的方法
Object obj = method.invoke(station, args);
return obj;
}
});
return proxyInstance;
}
}
Client
package com.hejiawang.pattern.proxy.jdk_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-01 10:49
**/
public class Client {
public static void main(String[] args) {
// 获取代理对象
// 1.创建代理工厂对象
ProxyFactory factory = new ProxyFactory();
// 2.使用factory对象的方法获取代理对象
SellTickets proxyObject = factory.getProxyObject();
// 3.调用卖电脑的方法
proxyObject.sell();
}
}
打印结果
2.动态代理原理分析
通过arthas来查看生成的代理类
加入死循环让进程不结束
package com.hejiawang.pattern.proxy.jdk_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-01 10:49
**/
public class Client {
public static void main(String[] args) {
// 获取代理对象
// 1.创建代理工厂对象
ProxyFactory factory = new ProxyFactory();
// 2.使用factory对象的方法获取代理对象
SellTickets proxyObject = factory.getProxyObject();
// 3.调用卖票的方法
proxyObject.sell();
System.out.println(proxyObject.getClass());
// 让程序一直运行
while(true){}
}
}
启动arthas,选择对应在跑的进程使用jad将答应的代理类类名输入jad反编译即可获得在jvm中运行的代理类
代理对象反编译后的源码
/*
* Decompiled with CFR.
*
* Could not load the following classes:
* com.hejiawang.pattern.proxy.jdk_proxy.SellTickets
*/
package com.sun.proxy;
import com.hejiawang.pattern.proxy.jdk_proxy.SellTickets;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy
implements SellTickets {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler invocationHandler) {
super(invocationHandler);
}
public final boolean equals(Object object) {
try {
return (Boolean)this.h.invoke(this, m1, new Object[]{object});
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString() {
try {
return (String)this.h.invoke(this, m2, null);
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void sell() {
try {
this.h.invoke(this, m3, null);
return;
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode() {
try {
return (Integer)this.h.invoke(this, m0, null);
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.hejiawang.pattern.proxy.jdk_proxy.SellTickets").getMethod("sell", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException noSuchMethodException) {
throw new NoSuchMethodError(noSuchMethodException.getMessage());
}
catch (ClassNotFoundException classNotFoundException) {
throw new NoClassDefFoundError(classNotFoundException.getMessage());
}
}
}
3.CGLIB动态代理
TrainStation
package com.hejiawang.pattern.proxy.cglib_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-06-30 21:18
**/
public class TrainStation {
public void sell() {
System.out.println("火车站卖票");
}
}
ProxyFactory
package com.hejiawang.pattern.proxy.cglib_proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-02 16:50
**/
// 代理对象工厂,用来获取代理对象
public class ProxyFactory implements MethodInterceptor {
// 声明火车站对象
private TrainStation station = new TrainStation();
public TrainStation getProxyObject() {
// 创建Enhancer对象,类似JDK代理中的Proxy类
Enhancer enhancer = new Enhancer();
// 设置父类的字节码对象
enhancer.setSuperclass(TrainStation.class);
// 设置回调函数
enhancer.setCallback(this);
// 创建代理对象
TrainStation proxyObject = (TrainStation)enhancer.create();
return proxyObject;
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// System.out.println("方法执行了");
System.out.println("代售点收取一定的服务费用(CGLib代理)");
// 要调用目标对象的方法
Object obj = method.invoke(station, objects);
return obj;
}
}
Client
package com.hejiawang.pattern.proxy.cglib_proxy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-02 17:07
**/
public class Client {
public static void main(String[] args) {
// 创建代理工厂对象
ProxyFactory factory = new ProxyFactory();
// 获取代理对象
TrainStation proxyObject= factory.getProxyObject();
// 调用代理对象中的sell方法卖票
proxyObject.sell();
}
}
打印结果
4.代理方式比较
2.适配器模式
1.类适配器模式
SDCard
package com.hejiawang.pattern.adapter.class_adapter;
public interface SDCard {
// 从SD卡中读取数据
String readSD();
// 往SD卡中写数据
void writeSD(String msg);
}
SDCardImpl
package com.hejiawang.pattern.adapter.class_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:22
**/
public class SDCardImpl implements SDCard {
public String readSD() {
String msg = "SDCard read msg : hello world SD";
return msg;
}
public void writeSD(String msg) {
System.out.println("SDCard write msg :" + msg);
}
}
TFCard
package com.hejiawang.pattern.adapter.class_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:17
**/
public interface TFCard{
// 从TF卡中读取数据
String readTF();
// 往TF卡中写数据
void writeTF(String msg);
}
TFCardImpl
package com.hejiawang.pattern.adapter.class_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:19
**/
public class TFCardImpl implements TFCard {
public String readTF() {
String msg = "TFCard read msg : hello world TFcard";
return msg;
}
public void writeTF(String msg) {
System.out.println("TFCard write msg :" + msg);
}
}
Computer
package com.hejiawang.pattern.adapter.class_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:23
**/
//计算器类
public class Computer {
// 从SD卡中读取数据
public String readSD(SDCard sdCard){
if(sdCard == null){
throw new NullPointerException("sdCard is not null");
}
return sdCard.readSD();
}
}
SDAdapterTF
package com.hejiawang.pattern.adapter.class_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:28
**/
public class SDAdapterTF extends TFCardImpl implements SDCard {
public String readSD() {
System.out.println("adapter read tf card");
return readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
writeTF(msg);
}
}
Client
package com.hejiawang.pattern.adapter.class_adapter;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:25
**/
public class Client {
public static void main(String[] args) {
// 创建计算机对象
Computer computer = new Computer();
// 读取SD卡中的数据
String msg = computer.readSD(new SDCardImpl());
System.out.println(msg);
System.out.println("=================");
// 使用该电脑读取TF卡中的数据
// 定义适配器类
String msg1 = computer.readSD(new SDAdapterTF());
System.out.println(msg1);
}
}
打印结果
2.对象适配器模式
SDCard
package com.hejiawang.pattern.adapter.object_adapter;
public interface SDCard {
// 从SD卡中读取数据
String readSD();
// 往SD卡中写数据
void writeSD(String msg);
}
SDCardImpl
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:22
**/
public class SDCardImpl implements SDCard {
public String readSD() {
String msg = "SDCard read msg : hello world SD";
return msg;
}
public void writeSD(String msg) {
System.out.println("SDCard write msg :" + msg);
}
}
TFCard
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:17
**/
public interface TFCard{
// 从TF卡中读取数据
String readTF();
// 往TF卡中写数据
void writeTF(String msg);
}
TFCardImpl
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:19
**/
public class TFCardImpl implements TFCard {
public String readTF() {
String msg = "TFCard read msg : hello world TFcard";
return msg;
}
public void writeTF(String msg) {
System.out.println("TFCard write msg :" + msg);
}
}
Computer
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:23
**/
//计算器类
public class Computer {
// 从SD卡中读取数据
public String readSD(SDCard sdCard){
if(sdCard == null){
throw new NullPointerException("sdCard is not null");
}
return sdCard.readSD();
}
}
SDAdapterTF
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:28
**/
public class SDAdapterTF implements SDCard {
// 声明适配者类
private TFCard tfCard;
public SDAdapterTF(TFCard tfCard) {
this.tfCard = tfCard;
}
public String readSD() {
System.out.println("adapter read tf card");
return tfCard.readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
tfCard.writeTF(msg);
}
}
Client
package com.hejiawang.pattern.adapter.object_adapter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 09:25
**/
public class Client {
public static void main(String[] args) {
// 创建计算机对象
Computer computer = new Computer();
// 读取SD卡中的数据
String msg = computer.readSD(new SDCardImpl());
System.out.println(msg);
System.out.println("=================");
// 使用该电脑读取TF卡中的数据
// 创建适配器对象
SDAdapterTF sdAdapterTF = new SDAdapterTF(new TFCardImpl());
// 定义适配器类
String msg1 = computer.readSD(sdAdapterTF);
System.out.println(msg1);
}
}
打印结果
3.jdk源码解析
3.装饰者模式
1.案例
FastFood 快餐类(抽象构建角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 10:10
**/
//快餐类(抽象构建角色)
public abstract class FastFood {
private float price;//价格
private String desc; //描述
public FastFood(float price, String desc) {
this.price = price;
this.desc = desc;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public abstract float cost();
}
FriedNoodles 炒面(具体构建角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 10:15
**/
//炒面(具体构建角色)
public class FriedNoodles extends FastFood{
public FriedNoodles() {
super(12,"炒面");
}
@Override
public float cost(){
return getPrice();
}
}
FriedRice 炒饭(具体构建角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 10:13
**/
// 炒饭(具体构建角色)
public class FriedRice extends FastFood{
public FriedRice() {
super(10,"炒饭");
}
@Override
public float cost(){
return getPrice();
}
}
Garnish 装饰者(抽象装饰者角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 10:16
**/
// 装饰者(抽象装饰者角色)
public abstract class Garnish extends FastFood{
// 声明快餐类的变量
private FastFood fastFood;
public Garnish( FastFood fastFood,float price, String desc) {
super(price, desc);
this.fastFood = fastFood;
}
public FastFood getFastFood() {
return fastFood;
}
public void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}
}
Egg 鸡蛋类(具体的装饰者角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 11:14
**/
// 鸡蛋类(具体的装饰者角色)
public class Egg extends Garnish{
public Egg(FastFood fastFood) {
super(fastFood,1,"鸡蛋");
}
@Override
public float cost(){
// 计算价格
return getPrice() + getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
Bacon 培根类(具体的装饰者角色)
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 11:14
**/
// 培根类(具体的装饰者角色)
public class Bacon extends Garnish{
public Bacon(FastFood fastFood) {
super(fastFood,2,"培根");
}
@Override
public float cost(){
// 计算价格
return getPrice() + getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
Client
package com.hejiawang.pattern.decorator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 15:47
**/
public class Client {
public static void main(String[] args) {
// 点一份炒饭
FastFood food = new FriedRice();
System.out.println(food.getDesc() + " " + food.cost() + "元");
System.out.println("==============");
// 在上面的炒饭中加一个鸡蛋
food = new Egg(food);
System.out.println(food.getDesc() + " " + food.cost() + "元");
System.out.println("==============");
// 再加一个鸡蛋
food = new Egg(food);
System.out.println(food.getDesc() + " " + food.cost() + "元");
System.out.println("==============");
food = new Bacon(food);
System.out.println(food.getDesc() + " " + food.cost() + "元");
}
}
打印结果
2.jdk中的使用
3.代理和装饰的区别
4.桥接模式
VideoFile 视频文件(实现化角色)
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 16:43
**/
//视频文件(实现化角色)
public interface VideoFile{
// 解码功能
void decode(String fileName);
}
RmvbFile rmv视频文件(具体的实现化角色 )
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 16:47
**/
//rmv视频文件(具体的实现化角色 )
public class RmvbFile implements VideoFile {
public void decode(String fileName) {
System.out.println("rmvb视频文件:" + fileName);
}
}
AviFile avi视频文件(具体的实现化角色 )
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 16:46
**/
//avi视频文件(具体的实现化角色 )
public class AviFile implements VideoFile {
public void decode(String fileName) {
System.out.println("avi视屏文件:" + fileName);
}
}
OpratingSystem 抽象的操作系统类(抽象变化角色)
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 16:48
**/
//抽象的操作系统类(抽象变化角色)
public abstract class OpratingSystem {
// 声明videFile变量
protected VideoFile videoFile;
public OpratingSystem(VideoFile videoFile){
this.videoFile = videoFile;
}
public abstract void play(String fileName);
}
Mac 操作系统(扩展抽象化角色)
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 18:49
**/
//Mac 操作系统(扩展抽象化角色)
public class Mac extends OpratingSystem {
public Mac(VideoFile videoFile) {
super(videoFile);
}
@Override
public void play(String fileName) {
videoFile.decode(fileName);
}
}
Windows 扩展抽象化角色(windows操作系统)
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 18:41
**/
//扩展抽象化角色(windows操作系统)
public class Windows extends OpratingSystem{
public Windows(VideoFile videoFile) {
super(videoFile);
}
@Override
public void play(String fileName) {
videoFile.decode(fileName);
}
}
Client
package com.hejiawang.pattern.bridge;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 18:50
**/
public class Client {
public static void main(String[] args) {
// 创建mac系统对象
OpratingSystem system = new Mac(new AviFile());
// 使用操作系统播放视频文件
system.play("战狼三");
}
}
打印结果
5.外观模式
1.案例
TV
package com.hejiawang.pattern.facade;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:04
**/
public class TV {
public void on (){
System.out.println("打开电视机。。。。");
}
public void off (){
System.out.println("关闭电视机。。。。");
}
}
Light
package com.hejiawang.pattern.facade;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:03
**/
public class Light {
public void on (){
System.out.println("打开电灯。。。。");
}
public void off (){
System.out.println("关闭电灯。。。。");
}
}
AirCondition
package com.hejiawang.pattern.facade;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:05
**/
public class AirCondition {
public void on (){
System.out.println("打开空调。。。。");
}
public void off (){
System.out.println("关闭空调。。。。");
}
}
SmartAplliancesFacade
package com.hejiawang.pattern.facade;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:05
**/
public class SmartAplliancesFacade {
// 聚合电灯对象,电视机对象,空调对象
private Light light;
private TV tv;
private AirCondition airCondition;
public SmartAplliancesFacade() {
light = new Light();
tv = new TV();
airCondition = new AirCondition();
}
// 通过语言控制
public void say (String message){
if (message.contains("打开")){
on();
}else if(message.contains("关闭")){
off();
} else {
System.out.println("我听不懂你说的!!!");
}
}
// 一键打开方法
private void on(){
light.on();
tv.on();
airCondition.on();
}
// 一键关闭方法
private void off(){
light.off();
tv.off();
airCondition.off();
}
}
Client
package com.hejiawang.pattern.facade;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:10
**/
public class Client {
public static void main(String[] args) {
// 创建智能音箱对象
SmartAplliancesFacade facade = new SmartAplliancesFacade();
// 控制家电
facade.say("打开家电");
System.out.println("=======");
facade.say("关闭家电");
}
}
2.源码解析
6.组合模式
1.案例
代码实现菜单
MenuComponent 属于抽象根节点
package com.hejiawang.pattern.combination;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:32
**/
//菜单组件 属于抽象根节点
public abstract class MenuComponent {
// 菜单组件的名称
protected String name;
// 菜单组件的层级
protected int level;
// 添加子菜单
public void add(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
// 移除子菜单
public void remove(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
// 获取指定的子菜单
public MenuComponent getChild(int index){
throw new UnsupportedOperationException();
}
// 获取菜单或者菜单项的名称
public String getName(){
return name;
}
// 打印菜单名称的方法(包括子菜单和子菜单项)
public abstract void print();
}
Menu 菜单类:属于树枝节点
package com.hejiawang.pattern.combination;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:37
**/
//菜单类:属于树枝节点
public class Menu extends MenuComponent{
// 菜单可以有多个子菜单或者子菜单项
private List<MenuComponent> menuComponentList = new ArrayList<MenuComponent>();
public Menu(String name,int level) {
this.name = name;
this.level = level;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
@Override
public MenuComponent getChild(int index) {
return menuComponentList.get(index);
}
@Override
public void print() {
// 打印菜单名称
for (int i = 0 ; i < level ; i++){
System.out.print("--");
}
System.out.println(name);
// 打印子菜单或者子菜单项名称
for (MenuComponent component:menuComponentList){
component.print();
}
}
}
MenuItem 菜单项类:属于叶子节点
package com.hejiawang.pattern.combination;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:45
**/
//菜单项类:属于叶子节点
public class MenuItem extends MenuComponent {
public MenuItem(String name,int level) {
this.name = name ;
this.level = level;
}
@Override
public void print() {
// 打印菜单项的名称
for (int i = 0 ; i < level ; i++){
System.out.print("--");
}
System.out.println(name);
}
}
Client
package com.hejiawang.pattern.combination;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 19:49
**/
public class Client {
public static void main(String[] args) {
// 创建菜单树
MenuComponent menu1 = new Menu("菜单管理",2);
menu1.add(new MenuItem("页面访问",3));
menu1.add(new MenuItem("展开菜单",3));
menu1.add(new MenuItem("编辑菜单",3));
menu1.add(new MenuItem("删除菜单",3));
menu1.add(new MenuItem("新增菜单",3));
MenuComponent menu2 = new Menu("权限管理",2);
menu2.add(new MenuItem("页面访问",3));
menu2.add(new MenuItem("提交保存",3));
MenuComponent menu3 = new Menu("角色管理",2);
menu3.add(new MenuItem("页面访问",3));
menu3.add(new MenuItem("新增角色",3));
menu3.add(new MenuItem("修改角色",3));
// 创建一级菜单
MenuComponent component = new Menu("系统管理",1);
component.add(menu1);
component.add(menu2);
component.add(menu3);
// 打印菜单名称(如果有子菜单,一块带你)
component.print();
}
}
打印结果
7.享元模式
1.案例
AbstractBox
package com.hejiawang.pattern.flyweight;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:23
**/
// 抽象享元角色
public abstract class AbstractBox {
// 获取图形的方法
public abstract String getShape();
// 显示图形及颜色
public void display(String color){
System.out.println("方块形状:"+getShape()+",颜色:" + color);
}
}
IBOX
package com.hejiawang.pattern.flyweight;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:26
**/
//I图形类(具体享元角色)
public class IBOX extends AbstractBox {
@Override
public String getShape() {
return "I";
}
}
LBOX
package com.hejiawang.pattern.flyweight;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:26
**/
//L图形类(具体享元角色)
public class LBOX extends AbstractBox {
@Override
public String getShape() {
return "L";
}
}
OBOX
package com.hejiawang.pattern.flyweight;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:26
**/
//O图形类(具体享元角色)
public class OBOX extends AbstractBox {
@Override
public String getShape() {
return "O";
}
}
BoxFactory
package com.hejiawang.pattern.flyweight;
import javax.swing.*;
import java.util.HashMap;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:28
**/
// 工厂类,将该类设计为单例
public class BoxFactory {
private HashMap<String,AbstractBox> map;
// 在构造方法中进行初始化操作
private BoxFactory() {
map = new HashMap<String, AbstractBox>();
map.put("I",new IBOX());
map.put("L",new LBOX());
map.put("O",new OBOX());
}
private static BoxFactory factory = new BoxFactory();
// 提供一个方法获取该工厂类对象
public static BoxFactory getInstance(){
return factory;
}
// 根据名称获取图形对象
public AbstractBox getShape(String name){
return map.get(name);
}
}
Client
package com.hejiawang.pattern.flyweight;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:33
**/
public class Client {
public static void main(String[] args) {
// 获取I图形对象
AbstractBox box1 = BoxFactory.getInstance().getShape("I");
box1.display("灰色");
// 获取L图形对象
AbstractBox box2 = BoxFactory.getInstance().getShape("L");
box2.display("绿色");
// 获取O图形对象
AbstractBox box3 = BoxFactory.getInstance().getShape("O");
box3.display("灰色");
// 获取O图形对象
AbstractBox box4 = BoxFactory.getInstance().getShape("O");
box4.display("红色");
//
System.out.println("两次获取到的O图形对象是否是同一个对象:"+(box3 == box4));
}
}
打印结果
2.jdk源码
Interger使用了享元模式
package com.hejiawang.pattern.flyweight.jdk;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 20:43
**/
public class Demo {
public static void main(String[] args) {
Integer i1 = 127;
Integer i2 = 127;
System.out.println("i1和i2对象是否是同一个对象?" + (i1 == i2));
Integer i3 = 128;
Integer i4 = 128;
System.out.println("i3和i4对象是否是同一个对象?" + (i3 == i4));
}
}
打印结果
反编译
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
3.行为型模式
1.模板方法模式
1.案例
AbstractClass
package com.hejiawang.pattern.template;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:08
**/
//抽象类
public abstract class AbstractClass {
// 模板方法定义
public final void cookProcess(){
pourOil();
heatOil();
pourVegetable();
pourSauce();
fry();
}
public void pourOil(){
System.out.println("倒油");
}
// 第二步:热油是一样的,所以直接实现
public void heatOil(){
System.out.println("热油");
}
// 第三步:倒蔬菜是不一样的(一个下包菜,一个下菜心)
public abstract void pourVegetable();
// 第四步:倒调味料是不一样的
public abstract void pourSauce();
// 第五步:翻炒是一样的,所以直接实现
public void fry(){
System.out.println("翻炒");
}
}
ConcreteClass_BaoCai
package com.hejiawang.pattern.template;
import com.hejiawang.pattern.flyweight.AbstractBox;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:14
**/
// 炒包菜类
public class ConcreteClass_BaoCai extends AbstractClass {
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是包菜");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是辣椒");
}
}
ConcreteClass_CaiXin
package com.hejiawang.pattern.template;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:15
**/
public class ConcreteClass_CaiXin extends AbstractClass {
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是菜心");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是蒜蓉");
}
}
Client
package com.hejiawang.pattern.template;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:16
**/
public class Client {
public static void main(String[] args) {
// 炒包菜
// 创建对象
ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();
// 调用炒菜的功能
baoCai.cookProcess();
}
}
打印结果
2.jdk源码
public abstract int read() throws IOException;
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read(); //调用了无参的read方法,即必须要求子类的实现的read方法,即实现了反向控制
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
2.策略模式
1.案例
Strategy
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:31
**/
//抽象策略类
public interface Strategy {
void show();
}
StrategyA
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:32
**/
//具体策略类
public class StrategyA implements Strategy {
public void show() {
System.out.println("买一送一");
}
}
StrategyB
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:33
**/
public class StrategyB implements Strategy {
public void show() {
System.out.println("满200减50");
}
}
StrategyC
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:33
**/
public class StrategyC implements Strategy {
public void show() {
System.out.println("满1000减200");
}
}
SalesMan
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:34
**/
public class SalesMan {
// 聚合策略类对象
private Strategy strategy;
public SalesMan(Strategy strategy){
this.strategy = strategy;
}
// 有促销员展示促销活动给用户
public void salesManShow(){
strategy.show();
}
}
Client
package com.hejiawang.pattern.strategy;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-04 21:36
**/
public class Client {
public static void main(String[] args) {
// 春节来了,使用春节促销活动
SalesMan salesMan = new SalesMan(new StrategyA());
salesMan.salesManShow();
System.out.println("===============");
// 中秋节到了,使用中秋节的促销
SalesMan salesMan2 = new SalesMan(new StrategyB());
salesMan2.salesManShow();
// 圣诞节到了,使用中秋节的促销
System.out.println("===============");
SalesMan salesMan3 = new SalesMan(new StrategyC());
salesMan3.salesManShow();
}
}
打印结果
2.jdk源码
3.命令模式
1.案例
Order
package com.hejiawang.pattern.command;
import java.util.HashMap;
import java.util.Map;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 09:50
**/
//订单类
public class Order {
// 餐桌号
private int diningTable;
// 所下的餐品及份数
private Map<String,Integer> foodDir = new HashMap<String, Integer>();
public int getDiningTable() {
return diningTable;
}
public void setDiningTable(int diningTable) {
this.diningTable = diningTable;
}
public Map<String, Integer> getFoodDir() {
return foodDir;
}
public void setFood(String name,int num) {
foodDir.put(name,num);
}
}
Command
package com.hejiawang.pattern.command;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 09:55
**/
//抽象命令类
public interface Command {
void execute();
}
OrderCommand
package com.hejiawang.pattern.command;
import java.util.Map;
import java.util.Set;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 09:57
**/
public class OrderCommand implements Command {
// 持有接受者对象
private SenioChef receiver;
private Order order;
public OrderCommand(SenioChef receiver,Order order){
this.receiver = receiver;
this.order = order;
}
public void execute() {
System.out.println(order.getDiningTable()+"桌的订单:");
Map<String,Integer> foodDir = order.getFoodDir();
// 遍历map集合
Set<String> keys = foodDir.keySet();
for (String foodName : keys){
receiver.makeFood(foodName,foodDir.get(foodName));
}
System.out.println(order.getDiningTable()+"桌的饭准备完毕!!!");
}
}
SenioChef
package com.hejiawang.pattern.command;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 09:54
**/
public class SenioChef {
public void makeFood(String name,int num){
System.out.println(num + "份" + name);
}
}
Client
package com.hejiawang.pattern.command;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 10:24
**/
public class Client {
public static void main(String[] args) {
// 创建第一个订单对象
Order order1 = new Order();
order1.setDiningTable(1);
order1.setFood("西红柿鸡蛋面",1);
order1.setFood("小杯可乐",2);
// 创建第二个订单对象
Order order2 = new Order();
order2.setDiningTable(2);
order2.setFood("尖椒肉丝盖饭",1);
order2.setFood("小杯雪碧",1);
// 创建厨师对象
SenioChef receiver = new SenioChef();
// 创建命令对象
OrderCommand cmd1 = new OrderCommand(receiver,order1);
OrderCommand cmd2 = new OrderCommand(receiver,order2);
// 创建调用者(服务员对象)
Waitor invoke = new Waitor();
invoke.setCommands(cmd1);
invoke.setCommands(cmd2);
// 让服务员发起命令
invoke.orderUp();
}
}
打印结果
2.jdk源码
4.责任链模式
1.案例
Handler
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:17
**/
// 抽象处理者类
public abstract class Handler {
protected final static int NUM_ONE = 1 ;
protected final static int NUM_THREE = 3 ;
protected final static int NUM_SEVEN = 7 ;
// 该领导处理的请求天数区间
private int numStart;
private int numEnd;
// 声明后继者(声明上级领导)
private Handler nextHandler;
public Handler(int numStart){
this.numStart = numStart;
}
public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}
// 设置上级领导对象
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
// 各级领导处理请假条的方法`在这里插入代码片`
protected abstract void handlerLeave(LeaveRequest leaveRequest);
// 提交请假条
public final void submit(LeaveRequest leaveRequest){
// 该领导进行审批
this.handlerLeave(leaveRequest);
if (this.nextHandler != null && leaveRequest.getNum() > this.numEnd){
// 提交给上级领导进行审批
this.nextHandler.submit(leaveRequest);
}else{
System.out.println("流程结束");
}
}
}
GroupLeader
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:26
**/
//小组长类
public class GroupLeader extends Handler {
public GroupLeader() {
super(0,Handler.NUM_ONE);
}
@Override
protected void handlerLeave(LeaveRequest leaveRequest) {
System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天,"+leaveRequest.getContent());
System.out.println("小组长审批:同意");
}
}
Manager
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:26
**/
//部门经理类
public class Manager extends Handler {
public Manager() {
super(Handler.NUM_ONE,Handler.NUM_THREE);
}
@Override
protected void handlerLeave(LeaveRequest leaveRequest) {
System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天,"+leaveRequest.getContent());
System.out.println("部门经理审批:同意");
}
}
GeneralManager
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:26
**/
//总经理类
public class GeneralManager extends Handler {
public GeneralManager() {
super(Handler.NUM_THREE,Handler.NUM_SEVEN);
}
@Override
protected void handlerLeave(LeaveRequest leaveRequest) {
System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天,"+leaveRequest.getContent());
System.out.println("总经理审批:同意");
}
}
LeaveRequest
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:15
**/
// 请假条类
public class LeaveRequest {
// 姓名
private String name;
// 请假天数
private int num;
// 请假内容
private String content;
public LeaveRequest(String name, int num, String content) {
this.name = name;
this.num = num;
this.content = content;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Client
package com.hejiawang.pattern.responsibility;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 12:33
**/
public class Client {
public static void main(String[] args) {
// 创建一个请假条对象
LeaveRequest leaveRequest = new LeaveRequest("小明",4,"身体不适");
// 创建各级领导对象
GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();
// 设置处理链
groupLeader.setNextHandler(manager);
manager.setNextHandler(generalManager);
// 小明提交请假申请
groupLeader.submit(leaveRequest);
}
}
打印结果
2.jdk源码分析
打印结果
5.状态模式
1.原始案例
ILift
package com.hejiawang.pattern.state.before;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 13:11
**/
// 电梯接口
public interface ILift {
// 定义四哥电梯状态的常量
int OPENING_STATE = 1;
int CLOSING_STATE = 2;
int RUNNING_STATE = 3;
int STOPPING_STATE = 4;
// 设置电梯状态的功能
void setState(int state);
// 电梯操作功能
void open();
void close();
void run();
void stop();
}
Lift
package com.hejiawang.pattern.state.before;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 13:14
**/
public class Lift implements ILift {
// 声明一个记录当前电梯的状态
private int state ;
public void setState(int state) {
this.state = state;
}
public void open() {
switch (state){
case OPENING_STATE :
// 什么事都不做
break;
case CLOSING_STATE :
System.out.println("电梯门打开了。。。");
setState(OPENING_STATE);
break;
case RUNNING_STATE :
// 什么事都不做
break;
case STOPPING_STATE :
System.out.println("电梯门打开了。。。");
setState(OPENING_STATE);
break;
}
}
public void close() {
switch (state){
case OPENING_STATE :
System.out.println("电梯门关了。。。");
setState(CLOSING_STATE);
break;
case CLOSING_STATE :
// 什么事都不做
break;
case RUNNING_STATE :
// 什么事都不做
break;
case STOPPING_STATE :
// 什么事都不做
break;
}
}
public void run() {
switch (state){
case OPENING_STATE :
// 什么事都不做
break;
case CLOSING_STATE :
System.out.println("电梯开始运行了。。。");
setState(RUNNING_STATE);
break;
case RUNNING_STATE :
// 什么事都不做
break;
case STOPPING_STATE :
System.out.println("电梯开始运行了。。。");
setState(RUNNING_STATE);
break;
}
}
public void stop() {
switch (state){
case OPENING_STATE :
// 什么事都不做
break;
case CLOSING_STATE :
System.out.println("电梯停止了。。。");
setState(STOPPING_STATE);
break;
case RUNNING_STATE :
System.out.println("电梯停止了。。。");
setState(STOPPING_STATE);
break;
case STOPPING_STATE :
// 什么事都不做
break;
}
}
}
Client
package com.hejiawang.pattern.state.before;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:40
**/
public class Client {
public static void main(String[] args) {
// 创建电梯对象
Lift lift = new Lift();
// 设置电梯当前状态
lift.setState(ILift.OPENING_STATE);
lift.open();
lift.close();
lift.run();
lift.stop();
}
}
打印结果
2.状态模式修改后案例
Context
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:48
**/
//环境角色类
public class Context {
public final static OpeningState OPENING_STATE = new OpeningState();
public final static ClosingState CLOSING_STATE = new ClosingState();
public final static RunningState RUNNING_STATE = new RunningState();
public final static StoppingState STOPPING_STATE = new StoppingState();
// 定义一个当前电梯状态变量
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
// 设置当前状态对象
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
// 设置当前状态对象中的context对象
this.liftState.setContext(this);
}
public void open(){
this.liftState.open();
}
public void close(){
this.liftState.close();
}
public void run(){
this.liftState.run();
}
public void stop(){
this.liftState.stop();
}
}
LiftState
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:47
**/
//抽象状态类
public abstract class LiftState {
// 声明环境角色类变量
protected Context context;
public void setContext(Context context) {
this.context = context;
}
// 电梯开启操作
public abstract void open();
// 电梯关闭操作
public abstract void close();
// 电梯运行操作
public abstract void run();
// 电梯停止操作
public abstract void stop();
}
RunningState
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:51
**/
//电梯运行状态类
public class RunningState extends LiftState {
// 当前状态要执行的方法
@Override
public void open() {
// 什么都不做
}
@Override
public void close() {
// 什么都不做
}
@Override
public void run() {
System.out.println("电梯运行。。。");
}
@Override
public void stop() {
super.context.setLiftState(Context.STOPPING_STATE);
super.context.getLiftState().stop();
}
}
StoppingState
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:52
**/
//电梯停止状态类
public class StoppingState extends LiftState {
// 当前状态要执行的方法
@Override
public void open() {
// 状态修改
super.context.setLiftState(Context.OPENING_STATE);
super.context.getLiftState().open();
}
@Override
public void close() {
super.context.setLiftState(Context.CLOSING_STATE);
super.context.getLiftState().close();
}
@Override
public void run() {
super.context.setLiftState(Context.RUNNING_STATE);
super.context.run();
}
@Override
public void stop() {
System.out.println("电梯停止。。。");
}
}
OpeningState
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:49
**/
//电梯开启状态类
public class OpeningState extends LiftState{
// 当前状态要执行的方法
@Override
public void open() {
System.out.println("电梯门开启。。。");
}
@Override
public void close() {
// 修改状态
super.context.setLiftState(Context.CLOSING_STATE);
// 调用当前状态中context中的close方法
super.context.close();
}
@Override
public void run() {
// 什么都不做
}
@Override
public void stop() {
// 什么都不做
}
}
ClosingState
package com.hejiawang.pattern.state.after;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-05 14:51
**/
public class ClosingState extends LiftState {
@Override
public void open() {
// 修改状态
super.context.setLiftState(Context.OPENING_STATE);
// 调用当前状态中context中的close方法
super.context.open();
}
@Override
public void close() {
System.out.println("电梯门关闭。。。");
}
@Override
public void run() {
// 修改状态
super.context.setLiftState(Context.RUNNING_STATE);
// 调用当前状态中context中的close方法
super.context.run();
}
@Override
public void stop() {
// 修改状态
super.context.setLiftState(Context.STOPPING_STATE);
// 调用当前状态中context中的close方法
super.context.stop();
}
}
Client
package com.hejiawang.pattern.state.after;
import com.hejiawang.pattern.template.ConcreteClass_BaoCai;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:23
**/
public class Client {
public static void main(String[] args) {
// 创建环境对象
Context context = new Context();
// 设置当前电梯装填
context.setLiftState(new ClosingState());
context.open();
context.close();
context.run();
context.stop();
}
}
打印结果
6.观察者模式
1.案例
Subject
package com.hejiawang.pattern.observer;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:47
**/
//抽象主题角色类
public interface Subject {
// 添加订阅者
void attach(Observer observer);
// 删除订阅者
void detach(Observer observer);
// 通知订阅者
void notify(String message);
}
Observer
package com.hejiawang.pattern.observer;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:48
**/
//抽象观察者
public interface Observer {
void update(String message);
}
SubscriptionSubject
package com.hejiawang.pattern.observer;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:50
**/
//具体主题角色类
public class SubscriptionSubject implements Subject {
// 定义一个集合,来存储对个观察者对象
private List<Observer> weiXinUserList = new ArrayList<Observer>();
public void attach(Observer observer) {
weiXinUserList.add(observer);
}
public void detach(Observer observer) {
weiXinUserList.remove(observer);
}
public void notify(String message) {
for (Observer observer: weiXinUserList){
// 调用观察者对象中update方法
observer.update(message );
}
}
}
WeiXinUser
package com.hejiawang.pattern.observer;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:54
**/
//具体的观察者角色
public class WeiXinUser implements Observer {
private String name;
public WeiXinUser(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + "-" + message);
}
}
Client
package com.hejiawang.pattern.observer;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 14:56
**/
public class Client {
public static void main(String[] args) {
// 1.创建公众号对象
SubscriptionSubject sbuject = new SubscriptionSubject();
// 2.订阅公众号
sbuject.attach(new WeiXinUser("飞鸽"));
sbuject.attach(new WeiXinUser("坤坤"));
sbuject.attach(new WeiXinUser("肥宅子"));
// 3.公众号更新,发出消息给订阅者(观察者对象)
sbuject.notify("日服男枪上线了!");
}
}
打印结果
2.jdk源码分析
继承Observable即是具体主题角色类,集成Observable类,调用notifyObservers()f方法
观察者实现Observer接口重写update方法
7.中介者模式
1.案例
Person
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:21
**/
//抽象同事类
public abstract class Person {
protected String name;
protected Mediator mediator;
public Person(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
}
Tenant
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:22
**/
//具体的同事角色类
public class Tenant extends Person {
public Tenant(String name, Mediator mediator) {
super(name, mediator);
}
// 和中介联系(沟通)
public void constact(String message){
mediator.constract(message,this);
}
// 获取信息
public void getMessage(String message){
System.out.println("租房者" + name + "获取到的信息是" + message);
}
}
HouseOwner
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:25
**/
public class HouseOwner extends Person {
public HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}
// 和中介联系(沟通)
public void constact(String message){
mediator.constract(message,this);
}
// 获取信息
public void getMessage(String message){
System.out.println("房主" + name + "获取到的信息是" + message);
}
}
Mediator
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:20
**/
public abstract class Mediator {
public abstract void constract(String message,Person person);
}
MediatorStructure
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:27
**/
//具体的终结者角色类
public class MediatorStructure extends Mediator{
// 聚合房主和租房者对象
private HouseOwner houseOwner;
private Tenant tenant;
public HouseOwner getHouseOwner() {
return houseOwner;
}
public void setHouseOwner(HouseOwner houseOwner) {
this.houseOwner = houseOwner;
}
public Tenant getTenant() {
return tenant;
}
public void setTenant(Tenant tenant) {
this.tenant = tenant;
}
@Override
public void constract(String message, Person person) {
if (person == tenant){
tenant.getMessage(message);
} else {
houseOwner.getMessage(message);
}
}
}
Client
package com.hejiawang.pattern.mediator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:29
**/
public class Client {
public static void main(String[] args) {
// 创建中介者对象
MediatorStructure mediator = new MediatorStructure();
// 创建租房者对象
Tenant tenant = new Tenant("肥宅子租房者",mediator);
// 创建房主对象
HouseOwner houseOwner = new HouseOwner("飞鸽包租公",mediator);
// 中介要知道具体的房主和租房者
mediator.setTenant(tenant);
mediator.setHouseOwner(houseOwner);
tenant.constact("我要租别墅");
houseOwner.constact("我这里有别墅,你要租吗?");
}
}
打印结果
8.迭代器模式
1.案例
Student
package com.hejiawang.pattern.iterator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:42
**/
public class Student {
private String name;
private String number;
public Student() {
}
public Student(String name, String number) {
this.name = name;
this.number = number;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number='" + number + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
StudentIterator
package com.hejiawang.pattern.iterator;
//抽象迭代器角色接口
public interface StudentIterator {
// 判断是否还有元素
boolean hasNext();
// 获取下一个元素
Student next();
}
StudentIteratorImpl
package com.hejiawang.pattern.iterator;
import java.util.List;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:44
**/
//具体迭代器角色
public class StudentIteratorImpl implements StudentIterator {
private List<Student> list;
private int position = 0; //用来记录遍历时的位置
public StudentIteratorImpl(List<Student> list) {
this.list = list;
}
public boolean hasNext() {
return position < list.size();
}
public Student next() {
// 从集合中获取指定位置的元素
Student currentSudent = list.get(position);
position++;
return currentSudent;
}
}
StudentAggregate
package com.hejiawang.pattern.iterator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 15:47
**/
//抽象聚合角色接口
public interface StudentAggregate {
// 添加学生功能
void addStudent(Student stu);
// 删除学生功能
void removeStudent(Student stu);
// 获取迭代器对象功能
StudentIterator getStudentIterator();
}
StudentAggregateImpl
package com.hejiawang.pattern.iterator;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:06
**/
public class StudentAggregateImpl implements StudentAggregate{
private List<Student> list = new ArrayList<Student>();
public void addStudent(Student stu) {
list.add(stu);
}
public void removeStudent(Student stu) {
list.remove(stu);
}
public StudentIterator getStudentIterator() {
return new StudentIteratorImpl(list);
}
}
Client
package com.hejiawang.pattern.iterator;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:12
**/
public class Client {
public static void main(String[] args) {
// 创建聚合对象
StudentAggregateImpl aggregate = new StudentAggregateImpl();
// 添加元素
aggregate.addStudent(new Student("张三","001"));
aggregate.addStudent(new Student("李四","002"));
aggregate.addStudent(new Student("王五","003"));
aggregate.addStudent(new Student("赵六","004"));
// 遍历聚合对象
// 1.获取迭代器对象
StudentIterator iterator = aggregate.getStudentIterator();
// 2.遍历
while(iterator.hasNext()){
// 3.获取元素
Student student = iterator.next();
System.out.println(student.toString());
}
}
}
打印结果
2.jdk源码
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
}
}
9.访问者模式
1.案例
Animal
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:35
**/
//抽象元素角色类
public interface Animal {
// 接收访问者访问的功能
void accept(Person person);
}
Cat
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:36
**/
//具体元素角色类(宠物猫)
public class Cat implements Animal {
public void accept(Person person) {
person.feed(this);//访问者给宠物猫喂食
System.out.println("喵喵喵~");
}
}
Dog
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:38
**/
//具体元素角色类(宠物狗)
public class Dog implements Animal {
public void accept(Person person) {
person.feed(this);//访问者给宠物猫喂食
System.out.println("汪汪汪~");
}
}
Person
package com.hejiawang.pattern.visitor;
//抽象访问者角色类
public interface Person {
// 喂食宠物狗
void feed(Cat cat);
// 喂食宠物猫
void feed(Dog dog);
}
Owner
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:39
**/
//具体访问者角色类(主人)
public class Owner implements Person{
public void feed(Cat cat) {
System.out.println("主人喂食猫");
}
public void feed(Dog dog) {
System.out.println("主人喂食狗");
}
}
Someone
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:40
**/
//具体访问者角色类(其他人)
public class Someone implements Person {
public void feed(Cat cat) {
System.out.println("其他人喂食猫");
}
public void feed(Dog dog) {
System.out.println("其他人喂食狗");
}
}
Home
package com.hejiawang.pattern.visitor;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:41
**/
//对象结构类
public class Home {
// 声明一个稽核对象,用来存储元素对象
private List<Animal> nodeList = new ArrayList<Animal>();
// 添加元素功能
public void add(Animal animal){
nodeList.add(animal);
}
public void action(Person person){
// 遍历集合,获取每一个元素,让访问者访问每一个元素
for (Animal animal:nodeList){
animal.accept(person);
}
}
}
Client
package com.hejiawang.pattern.visitor;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 16:44
**/
public class Client {
public static void main(String[] args) {
// 创建Home对象
Home home = new Home();
home.add(new Dog());
home.add(new Cat());
// 创建爱你主任对象
Owner owner = new Owner();
// 让主任喂食所有的宠物
home.action(owner);
}
}
打印结果
2.双分派技术
1.动态分派
2.静态分派
3.双分派
10.备忘录模式
1.案例
1.白箱备忘录模式
GameRole
package com.hejiawang.pattern.memento.white_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:09
**/
//游戏角色类(属于发起人角色)
public class GameRole {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
// 初始化内部状态
public void initState(){
this.vit = 100;
this.atk = 100;
this.def = 100;
}
// 战斗
public void fight(){
this.vit = 0;
this.atk = 0;
this.def = 0;
}
// 保存角色状态功能
public RoleStateMemento saveState(){
return new RoleStateMemento(vit,atk,def);
}
// 恢复角色状态
public void recoverState(RoleStateMemento roleStateMemento){
// 将备忘录中存储的状态复制给当前对象的成员
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}
// 展示状态功能
public void stateDisplay(){
System.out.println("角色生命力" + vit);
System.out.println("角色攻击力" + atk);
System.out.println("角色防御力" + def);
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
RoleStateMemento
package com.hejiawang.pattern.memento.white_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:12
**/
//备忘录角色类
public class RoleStateMemento {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
public RoleStateMemento() {
}
public RoleStateMemento(int vit, int atk, int def) {
this.vit = vit;
this.atk = atk;
this.def = def;
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
RoleStateCaretaker
package com.hejiawang.pattern.memento.white_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:19
**/
//备忘录对象管理对象
public class RoleStateCaretaker {
// 声明RoleStateMemento类型的变量
private RoleStateMemento roleStateMemento;
public RoleStateMemento getRoleStateMemento() {
return roleStateMemento;
}
public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
this.roleStateMemento = roleStateMemento;
}
}
Client
package com.hejiawang.pattern.memento.white_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:20
**/
public class Client {
public static void main(String[] args) {
System.out.println("---------作战前-----------");
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();
// 将该角色内部状态进行备份
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
roleStateCaretaker.setRoleStateMemento(gameRole.saveState());
System.out.println("---------作战后-----------");
// 损耗严重
gameRole.fight();
gameRole.stateDisplay();
System.out.println("---------恢复之前的状态-----------");
gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
gameRole.stateDisplay();
}
}
打印结果
2.黑箱备忘录模式
Memento
package com.hejiawang.pattern.memento.black_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:30
**/
//备忘录接口,对外提供窄接口
public interface Memento {
}
RoleStateCaretaker
package com.hejiawang.pattern.memento.black_box;
import com.hejiawang.pattern.memento.white_box.RoleStateMemento;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:19
**/
//备忘录对象管理对象
public class RoleStateCaretaker {
// 声明RoleStateMemento类型的变量
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
GameRole
package com.hejiawang.pattern.memento.black_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:09
**/
//游戏角色类(属于发起人角色)
public class GameRole {
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
private class RoleStateMemento implements Memento{
private int vit; //生命力
private int atk; //攻击力
private int def; //防御力
public RoleStateMemento() {
}
public RoleStateMemento(int vit, int atk, int def) {
this.vit = vit;
this.atk = atk;
this.def = def;
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
// 初始化内部状态
public void initState(){
this.vit = 100;
this.atk = 100;
this.def = 100;
}
// 战斗
public void fight(){
this.vit = 0;
this.atk = 0;
this.def = 0;
}
// 保存角色状态功能
public RoleStateMemento saveState(){
return new RoleStateMemento(vit,atk,def);
}
// 恢复角色状态
public void recoverState(Memento memento){
RoleStateMemento roleStateMemento = (RoleStateMemento)memento;
// 将备忘录中存储的状态复制给当前对象的成员
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}
// 展示状态功能
public void stateDisplay(){
System.out.println("角色生命力" + vit);
System.out.println("角色攻击力" + atk);
System.out.println("角色防御力" + def);
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
Client
package com.hejiawang.pattern.memento.black_box;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:20
**/
public class Client {
public static void main(String[] args) {
System.out.println("---------作战前-----------");
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();
// 将该角色内部状态进行备份
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
roleStateCaretaker.setMemento(gameRole.saveState());
System.out.println("---------作战后-----------");
// 损耗严重
gameRole.fight();
gameRole.stateDisplay();
System.out.println("---------恢复之前的状态-----------");
gameRole.recoverState(roleStateCaretaker.getMemento());
gameRole.stateDisplay();
}
}
打印结果
11.解释器模式
1.案例
Context
package com.hejiawang.pattern.interpreter;
import java.util.HashMap;
import java.util.Map;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:46
**/
//环境角色类
public class Context {
// 定义一个map稽核,用来存储变量及对应的值
private Map<Variable,Integer> map = new HashMap<Variable,Integer>();
// 添加变量的功能
public void assign(Variable var,Integer value ){
map.put(var,value);
}
// 根据变量获取对应的值
public int getValue(Variable var){
return map.get(var);
}
}
AbstractExperssion
package com.hejiawang.pattern.interpreter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:45
**/
//抽象表达式类
public abstract class AbstractExperssion {
public abstract int interpreter(Context context);
}
Variable
package com.hejiawang.pattern.interpreter;
import com.hejiawang.pattern.template.AbstractClass;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:47
**/
//变量类
public class Variable extends AbstractExperssion {
// 声明存储变量名的成员变量
private String name;
public Variable(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
@Override
public int interpreter(Context context) {
return context.getValue(this);
}
}
Minus
package com.hejiawang.pattern.interpreter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:49
**/
//减法表达式类
public class Minus extends AbstractExperssion{
// -号左边的表达式
private AbstractExperssion left;
// -号右边的表达式
private AbstractExperssion right;
public Minus(AbstractExperssion left, AbstractExperssion right) {
this.left = left;
this.right = right;
}
@Override
public int interpreter(Context context) {
// 将左边表达式的结果和右边表达式的结果相加 2-3
return left.interpreter(context) - right.interpreter(context);
}
@Override
public String toString() {
return "("+ left.toString() + " - " + right.toString() + ")";
}
}
Plus
package com.hejiawang.pattern.interpreter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:49
**/
//加法表达式类
public class Plus extends AbstractExperssion{
// +号左边的表达式
private AbstractExperssion left;
// +号右边的表达式
private AbstractExperssion right;
public Plus(AbstractExperssion left, AbstractExperssion right) {
this.left = left;
this.right = right;
}
@Override
public int interpreter(Context context) {
// 将左边表达式的结果和右边表达式的结果相加 2+3
return left.interpreter(context) + right.interpreter(context);
}
@Override
public String toString() {
return "("+ left.toString() + " + " + right.toString() + ")";
}
}
Client
package com.hejiawang.pattern.interpreter;
/**
* @description:
* @author: Mr.Wang
* @create: 2022-07-09 17:57
**/
public class Client {
public static void main(String[] args) {
Context context = new Context();
// 创建多个变量
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
Variable d = new Variable("d");
// 将环境变量存储到环境对象中
context.assign(a,1);
context.assign(b,2);
context.assign(c,3);
context.assign(d,4);
// 获取抽象语法树 a+b-c+d
AbstractExperssion experssion = new Minus(a,new Plus(new Minus(b,c),d));
// 计算
int result = experssion.interpreter(context);
System.out.println(experssion + " = " + result);
}
}
打印结果