本篇笔记对于JAVA23中设计模式,记录下来了21种,剩下的两种个人认为耦合度很高,看起来就很不舒服就没在本篇本章中做出记录
在软件工程中,类图是一种静态的结构图,描述了系统的类的集合,类的属性和类之间的关系,可以简化人们对系统的理解
类图是系统分析和设计阶段的产物,是系统测试和编码的重要模型
类使用包含类名,属性,和方法,且带有分割线的矩形来表示,如图下的Employee类,它包含name,age和address这三个属性以及worf()方法
属性/方法名称前加的加号和减号表示了这个属性/方法的可见性,表示可见性的符号有三种
+:表示public
-:表示private
#:表示protected
属性的完整表示方式是:可见性 名称 :类型 [ =缺省值]
方法的完整表示方式是: 可见性 名称(参数列表)返回值类型
关联关系是对象常用的一种引用关系,用于表示一类对象和另一类对象的联系,如:学生和老师,师傅和徒弟,妻子和丈夫等,关联关系是类与类中最常见的一种关系
对扩展开放,对修改关闭
在程序需要进行扩展的时候,不能去修改原有的代码,实现一个热插拔的效果,简言之,是为了使程序的扩展性好,易于维护和升级通过车案例说明
高层模块不应该依赖底层模块,两者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象,简单说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块的耦和
合成复用原则指的是:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
通常类的复用分为继承复用和合成复用两种
继承复用虽然有简单易实现的优点,但是它也存在以下缺点
单例模式分为懒汉式和饿汉式
饿汉式:类加载就会导致该单例对象被创建
懒汉式:类加载不会导致该单例对象被创建,而是首次使用对象才会被创建
/**
* @author LXY
* @desc 饿汉式,类加载的时候就会实例化
* @time 2023--12--22--9:54
*/
public class Singletons {
//私有构造方法,这样外部就无法通过构造方法来实例化对象
private Singletons(){}
//在本类中创建对象
private static Singletons singletons=new Singletons();
//外部可以通过对象.方法的方式拿到创建的实例对象
public static Singletons getInstance(){
return singletons;
}
}
public class Client {
public static void main(String[] args) {
Singletons instance = Singletons.getInstance();
Singletons instance2 = Singletons.getInstance();
System.out.println(instance==instance2); //结果为true证明是一个对象
}
}
/**
* @author LXY
* @desc 饿汉式通过静态代码块
* @time 2023--12--22--10:02
*/
public class Singgletons2 {
//私有化
private Singgletons2(){}
private static Singgletons2 singgletons2=null;
static {
singgletons2=new Singgletons2();
}
//外部可以通过对象.方法的方式拿到创建的实例对象
public static Singgletons2 getInstance(){
return singgletons2;
}
}
ps:静态变量会随着类的加载而创建,这样操作如果加载了一直不用势必会造成内存的浪费
/**
* @author LXY
* @desc 单例模式
* @time 2023--12--22--10:14
*/
public class Singletons3 {
//私有化构造器
private Singletons3(){}
//定义静态变量,并且使用volatile,volatile可以保证在多线程环境下的可见性和有序性
private static volatile Singletons3 Instance=null;
//初始化方法
public static Singletons3 getInstance() {
//双重检查的方式,既有了加锁安全的方式又不会造成因为每个线程都上锁的堵塞
if (Instance==null){
//对Instance是null的情况进行加锁,是写操作保证线程的安全
synchronized (Singletons3.class){
if (Instance==null){
Instance= new Singletons3();
}
}
}
return Instance;
}
}
/**
* @author LXY
* @desc 懒汉式,静态内部类实现
* @time 2023--12--22--10:24
*/
public class Singletons4 {
private Singletons4(){}
private static class SingletonsHead{
private final static Singletons4 SINGLETONS=new Singletons4();
}
public static Singletons4 getInstance(){
return SingletonsHead.SINGLETONS;
}
}
/**
* @author LXY
* @desc
* @time 2023--12--22--10:42
*/
public class Demo5 {
public static void main(String[] args) throws Exception{
// writeSingletons();
readSingletons();
readSingletons();
}
//读文件流
private static void readSingletons() throws Exception {
final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\20505\\Desktop\\ctg\\5.txt"));
Singletons4 instance = (Singletons4) objectInputStream.readObject();
System.out.println(instance);
objectInputStream.close();
}
//写文件流
private static void writeSingletons() throws Exception {
final Singletons4 instance = Singletons4.getInstance();
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\20505\\Desktop\\ctg\\5.txt"));
//写入对象
objectOutputStream.writeObject(instance);
//释放资源
objectOutputStream.close();
}
}
理由:writeObject是没有问题的,readObject也可以成功的读取到对象,但是
readObject底层他读出对象之后会判断对象中又没有readResolve()方法,如果有这个方法就返回里面的值,如果没有就返回一个新的对象,这就是为什么两次读出来的数据是不一样的
代码改正
/**
* @author LXY
* @desc 懒汉式,静态内部类实现
* @time 2023--12--22--10:24
*/
public class Singletons4 implements Serializable {
private Singletons4(){}
private static class SingletonsHead{
private final static Singletons4 SINGLETONS=new Singletons4();
}
public static Singletons4 getInstance(){
return SingletonsHead.SINGLETONS;
}
public Object readResolve(){
return SingletonsHead.SINGLETONS;
}
}
/**
* @author LXY
* @desc 咖啡的抽象类
* @time 2023--12--22--15:33
*/
public abstract class Coffee {
//咖啡名字
abstract String getName();
public void addMilk(){
System.out.println("加牛奶");
}
public void addsugar(){
System.out.println("加糖");
}
}
/**
* @author LXY
* @desc 美式咖啡
* @time 2023--12--22--15:35
*/
public class AmericanCoffee extends Coffee{
@Override
String getName() {
return "我是美式咖啡";
}
}
/**
* @author LXY
* @desc拿铁咖啡
* @time 2023--12--22--15:36
*/
public class LatteCoffee extends Coffee{
@Override
String getName() {
return "我是拿铁咖啡";
}
}
/**
* @author LXY
* @desc 咖啡店
* @time 2023--12--22--15:36
*/
public class CoffeeStore {
Coffee coffee=null;
public Coffee orderCoffee(String type){
if (type.equals("american")){
coffee=new AmericanCoffee();
}else if (type.equals("latte")){
coffee=new LatteCoffee();
}else {
throw new RuntimeException("对不起咖啡点完了");
}
//加糖,加牛奶
coffee.addsugar();
coffee.addMilk();
return coffee;
}
}
/**
* @author LXY
* @desc 测试类
* @time 2023--12--22--15:39
*/
public class Client {
public static void main(String[] args) {
//实例化咖啡店
CoffeeStore coffeeStore=new CoffeeStore();
//向咖啡店要一杯美式咖啡
final Coffee coffee = coffeeStore.orderCoffee("american");
System.out.println(coffee.getName());
}
}
/**
* @author LXY
* @desc 咖啡店
* @time 2023--12--22--15:36
*/
public class CoffeeStore {
Coffee coffee=null;
public Coffee orderCoffee(String type){
//调用咖啡简单工厂模式,
coffee=SimpleCoffeeFactory.getinterFactor(type);
//加糖,加牛奶
coffee.addsugar();
coffee.addMilk();
return coffee;
}
}
/**
* @author LXY
* @desc 咖啡工厂类,
* @time 2023--12--22--15:46
*/
public class SimpleCoffeeFactory {
public static Coffee getinterFactor(String type){
if (type.equals("american")){
return new AmericanCoffee();
}else if (type.equals("latte")){
return new LatteCoffee();
}else {
throw new RuntimeException("对不起咖啡点完了");
}
}
}
/**
* @author LXY
* @desc 咖啡的抽象类
* @time 2023--12--22--15:33
*/
public abstract class Coffee {
//咖啡名字
abstract String getName();
public void addMilk(){
System.out.println("加牛奶");
}
public void addsugar(){
System.out.println("加糖");
}
}
/**
* @author LXY
* @desc 美式咖啡
* @time 2023--12--22--15:35
*/
public class AmericanCoffee extends Coffee{
@Override
String getName() {
return "我是美式咖啡";
}
}
/**
* @author LXY
* @desc拿铁咖啡
* @time 2023--12--22--15:36
*/
public class LatteCoffee extends Coffee{
@Override
String getName() {
return "我是拿铁咖啡";
}
}
/**
* @author LXY
* @desc 接口
* @time 2023--12--22--16:02
*/
public interface CoffeeFactory {
Coffee createCoffeeFactory();
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:03
*/
public class AmericanCoffeeFactory implements CoffeeFactory{
@Override
public Coffee createCoffeeFactory() {
return new AmericanCoffee();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:04
*/
public class LatteCoffeeCoffeeFactory implements CoffeeFactory{
@Override
public Coffee createCoffeeFactory() {
return new LatteCoffee();
}
}
/**
* @author LXY
* @desc 咖啡店
* @time 2023--12--22--15:36
*/
public class CoffeeStore {
CoffeeFactory coffeeFactory=null;
public void setCoffee( CoffeeFactory coffeeFactory) {
this.coffeeFactory = coffeeFactory;
}
public Coffee orderCoffee(){
Coffee coffee = this.coffeeFactory.createCoffeeFactory();
//加糖,加牛奶
coffee.addsugar();
coffee.addMilk();
return coffee;
}
}
/**
* @author LXY
* @desc 测试类
* @time 2023--12--22--15:39
*/
public class Client {
public static void main(String[] args) {
//实例化咖啡店
CoffeeStore coffeeStore=new CoffeeStore();
//向咖啡店要一杯美式咖啡
coffeeStore.setCoffee(new AmericanCoffeeFactory());
final Coffee coffee = coffeeStore.orderCoffee();
System.out.println(coffee.getName());
}
}
/**
* @author LXY
* @desc 咖啡的抽象类
* @time 2023--12--22--15:33
*/
public abstract class Coffee {
//咖啡名字
abstract String getName();
public void addMilk(){
System.out.println("加牛奶");
}
public void addsugar(){
System.out.println("加糖");
}
}
/**
* @author LXY
* @desc 美式咖啡
* @time 2023--12--22--15:35
*/
public class AmericanCoffee extends Coffee {
@Override
String getName() {
return "我是美式咖啡";
}
}
/**
* @author LXY
* @desc拿铁咖啡
* @time 2023--12--22--15:36
*/
public class LatteCoffee extends Coffee {
@Override
String getName() {
return "我是拿铁咖啡";
}
}
/**
* @author LXY
* @desc 甜点
* @time 2023--12--22--16:47
*/
public abstract class Dessert {
abstract String getName() ;
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:48
*/
public class TimisuDessert extends Dessert{
@Override
String getName() {
return "我是提拉米苏";
}
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:49
*/
public class MoMusiDessert extends Dessert{
@Override
String getName() {
return "抹茶慕斯";
}
}
/**
* @author LXY
* @desc 风味,风味接口
* @time 2023--12--22--16:55
*/
public interface DessertFacory {
Coffee createcoffee();
Dessert createDesser();
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:57
*/
public class ItalyDessertFactory implements DessertFacory{
@Override
public Coffee createcoffee() {
return new LatteCoffee();
}
@Override
public Dessert createDesser() {
return new TimisuDessert();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--22--16:56
*/
public class AmericanDessrtFactory implements DessertFacory{
@Override
public Coffee createcoffee() {
return new AmericanCoffee();
}
@Override
public Dessert createDesser() {
return new MoMusiDessert();
}
}
/**
* @author LXY
* @desc 测试类
* @time 2023--12--22--15:39
*/
public class Client {
public static void main(String[] args) {
ItalyDessertFactory italyDessertFactory=new ItalyDessertFactory();
System.out.println("italyDessertFactory.createcoffee().getName() = " + italyDessertFactory.createcoffee().getName());
System.out.println("italyDessertFactory.createcoffee().getName() = " + italyDessertFactory.createDesser().getName());
}
}
可以通过工厂迷失+配置文件的方式接触工厂对象和产品对象的耦合,在工厂类中加载配置文件中的全类名,并创建对象进行存储,客户端如果需要对象,直接获取即可
american=com.rj.jand.patten.propper.AmericanCoffee
latte=com.rj.jand.patten.propper.LatteCoffee
/**
* @author LXY
* @desc 咖啡店
* @time 2023--12--22--15:36
*/
public class CoffeeStore {
//存储咖啡对象
private static HashMap<String,Coffee>map=new HashMap<>();
//通过读取配置文件+反射获取
static {
//加载Properties对象
Properties p=new Properties();
InputStream is = CoffeeStore.class.getClassLoader().getResourceAsStream("bean.properties");
try {
//加载读取
p.load(is);
Set<Object> keySet = p.keySet();
for (Object o : keySet) {
//通过反射拿到自己写的类名字(String)
String ClassName = p.getProperty((String) o);
//通过反射技术获取对象
final Class<?> aClass = Class.forName(ClassName);
final Coffee coffee = (Coffee)aClass.newInstance();
map.put((String)o, coffee);
}
}catch (Exception e){
}
}
public Coffee orderCoffee(String type){
return map.get(type);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--22--17:13
*/
public class Client {
public static void main(String[] args) {
CoffeeStore coffeeStore=new CoffeeStore();
final Coffee coffee = coffeeStore.orderCoffee("american");
System.out.println(coffee.getName());
final Coffee coffeee = coffeeStore.orderCoffee("latte");
System.out.println(coffeee.getName());
}
}
List list=new ArrayList();
list.add("1");
list.add("2");
final Iterator iterator = list.iterator();
使用迭代器遍历集合,获取集合中的元素而单列集合获取迭代器就使用到了工厂模式,我们看看类结构
Collection作为list的顶层父接口,引用了Iterator
我们现在是实现的是ArrayList,他的父类是List,list中又一个 Iterator iterator();的方法
ArrayList作为他的子类,实现了这个方法,返回了一个内部实现类,
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的内存地址
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有内存地址
Java中的object类中提供了clone()方法来实现浅克隆,cloneable接口是上面的类图中的抽象原型类,而实现了clineable接口的子实现类
就是具体的原型类,代码如下
/**
* @author LXY
* @desc
* @time 2023--12--23--14:33
*/
public class Certificate implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("恭喜本年度"+getName()+"荣获三好学生奖状,特发此证,以资鼓励");
}
@Override
protected Certificate clone() throws CloneNotSupportedException {
return (Certificate) super.clone();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--14:36
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//第一个对象
Certificate certificate=new Certificate();
//第二个帝乡
Certificate clone = certificate.clone();
certificate.setName("张三");
clone.setName("李四");
certificate.show();
clone.show();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--14:33
*/
public class Student implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--14:33
*/
public class Certificate implements Cloneable{
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public void show(){
System.out.println("恭喜本年度"+getStudent().getName()+"荣获三好学生奖状,特发此证,以资鼓励");
}
@Override
protected Certificate clone() throws CloneNotSupportedException {
return (Certificate) super.clone();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--14:36
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//第一个对象
Certificate certificate=new Certificate();
Student student = new Student();
student.setName("张三");
certificate.setStudent(student);
//第二个帝乡
Certificate clone = certificate.clone();
clone.getStudent().setName("李四");
certificate.show();
clone.show();
}
}
通过ObjectOutputStream和ObjectInputStream对象读写流,将对象进行深克隆
package com.rj.jand.patten.prototype;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @author LXY
* @desc
* @time 2023--12--23--14:36
*/
public class Client {
public static void main(String[] args) throws Exception{
//第一个对象
Certificate certificate=new Certificate();
Student student = new Student();
student.setName("张三");
certificate.setStudent(student);
//写对象操作
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\20505\\Desktop\\ctg\\a.txt"));
objectOutputStream.writeObject(certificate);
//读对象操作
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\20505\\Desktop\\ctg\\a.txt"));
Certificate clone = (Certificate) objectInputStream.readObject();
clone.getStudent().setName("李四");
certificate.show();
clone.show();
//关流
objectOutputStream.close();
objectInputStream.close();
}
}
创建共享单车
生产自行车是一个复杂的付过程,它包含了车架,车座等组件的生产。而车架又有碳纤维,铝合金等材质,车座又有橡胶,真皮等材质对于自行车的生产可以使用建造者模式
/**
* @author LXY
* @desc 实体
* @time 2023--12--23--15:36
*/
public class Bilke {
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;
}
@Override
public String toString() {
return "Bilke{" +
"frame='" + frame + '\'' +
", seat='" + seat + '\'' +
'}';
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--15:38
*/
public abstract class Builder {
protected Bilke bilke=new Bilke();
public abstract void builderFrame();
public abstract void builderSear();
public abstract Bilke createBilke();
}
/**
* @author LXY
* @desc 哈罗创建
* @time 2023--12--23--15:40
*/
public class MoBikeBuilder extends Builder{
@Override
public void builderFrame() {
bilke.setFrame("碳纤维");
}
@Override
public void builderSear() {
bilke.setSeat("橡胶");
}
@Override
public Bilke createBilke() {
return bilke;
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--15:42
*/
public class OfoBuilder extends Builder{
@Override
public void builderFrame() {
bilke.setFrame("铝合金");
}
@Override
public void builderSear() {
bilke.setSeat("真皮");
}
@Override
public Bilke createBilke() {
return bilke;
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--15:43
*/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Bilke construct(){
builder.builderFrame();
builder.builderSear();
return builder.createBilke();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--15:45
*/
public class Cilent {
public static void main(String[] args) {
Director director=new Director(new MoBikeBuilder());
final Bilke construct = director.construct();
System.out.println(construct);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--15:54
*/
public class Phone implements Serializable {
private String cpu;
private String screen;
private String memory;
private String mainboard;
private Phone(String cpu, String screen, String memory, String mainboard) {
this.cpu = cpu;
this.screen = screen;
this.memory = memory;
this.mainboard = mainboard;
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + 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;
}
public Phone bilder(){
return new Phone(this.cpu,this.screen,this.memory,this.mainboard);
}
}
}
由于某些原因需要给某对象提供一个代理以控制该对象的访问,这时访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象直接的中介
Java中的代理按照代理类生成实际不同又分为静态代理和动态代理,静态代理在编译期就产生,而动态代理类则是在Java运行时动态产生,动态代理又有JDK代理和CGLib代理两种
/**
* @author LXY
* @desc 火车站
* @time 2023--12--23--18:25
*/
public class TrainStation implements SellTickets{
@Override
public void sell() {
System.out.println("火车站售票成功");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--18:21
*/
public interface SellTickets {
void sell();
}
/**
* @author LXY
* @desc 代理类
* @time 2023--12--23--18:27
*/
public class Procypoint implements SellTickets{
private SellTickets sellTickets=new TrainStation();
@Override
public void sell() {
sellTickets.sell();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--18:26
*/
public class Client {
public static void main(String[] args) {
Procypoint procypoint=new Procypoint();
procypoint.sell();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--18:46
*/
public class Client {
public static void main(String[] args) {
Procypoint procypoint=new Procypoint();
procypoint.getproxyObject().sell();
}
}
/**
* @author LXY
* @desc 代理类
* @time 2023--12--23--18:27
*/
public class Procypoint {
//实例化火车站
private TrainStation sellTickets=new TrainStation();
public SellTickets getproxyObject(){
/**
* ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h
*/
return (SellTickets) Proxy.newProxyInstance(
sellTickets.getClass().getClassLoader(),
sellTickets.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理点收取一定的费用");
return method.invoke(sellTickets,args);
}
});
}
}
/**
* @author LXY
* @desc
* @time 2023--12--23--18:21
*/
public interface SellTickets {
void sell();
}
/**
* @author LXY
* @desc 火车站
* @time 2023--12--23--18:25
*/
public class TrainStation implements SellTickets {
@Override
public void sell() {
System.out.println("火车站售票成功");
}
}
public class Client {
public static void main(String[] args) {
Procypoint procypoint=new Procypoint();
procypoint.getproxyObject().sell();
}
}
return (SellTickets) Proxy.newProxyInstance(
sellTickets.getClass().getClassLoader(),
sellTickets.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理点收取一定的费用");
return method.invoke(sellTickets,args);
}
});
在invoke中通过method.invoke通过反射去调用对应的sell()方法,我们可以在这个步骤进行打印log日志啊,收取费用等等操作,是做一个功能的增强
/**
* @author LXY
* @desc
* @time 2023--12--23--19:22
*/
public class Client {
public static void main(String[] args) {
Procypoint procypoint=new Procypoint();
procypoint.getproxyObject().sell();
}
}
/**
* @author LXY
* @desc 代理类
* @time 2023--12--23--18:27
*/
public class Procypoint implements MethodInterceptor {
//实例化火车站
private TrainStation sellTickets=new TrainStation();
public TrainStation getproxyObject(){
//创建Enhancer对象
Enhancer enhancer = new Enhancer();
//设置父类的字节码对象
enhancer.setSuperclass(TrainStation.class);
//设置回调函数,传递的应该是MethodInterceptor对象,这里实现一下,传入this即可
enhancer.setCallback(this);
//创建代理对象
return (TrainStation) enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("收取代理费用了开始");
return method.invoke(sellTickets,objects);
}
}
/**
* @author LXY
* @desc 火车站
* @time 2023--12--23--18:25
*/
public class TrainStation implements SellTickets {
@Override
public void sell() {
System.out.println("火车站售票成功");
}
}
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
实现方式:定义一个适配器类来实现当前 系统的业务接口,同时又继承现有组件库中已经存在的组件
例:【读卡器案例】
现有一台电脑只能读取SD卡,而要读取到TF卡中的数据就要用到适配器模式,创建一个读卡器,将TF中的内容读取出来
/**
* @author LXY
* @desc TF卡
* @time 2023--12--24--13:43
*/
public interface TFCard {
String readTF();
void writeTF(String msg);
}
/**
* @author LXY
* @desc
* @time 2023--12--24--13:44
*/
public class TFCardImple implements TFCard{
@Override
public String readTF() {
return "TF读取成功,内容是:Hello Word";
}
@Override
public void writeTF(String msg) {
System.out.println("TF存储成功,内容是:"+msg);
}
}
/**
* @author LXY
* @desc SD卡
* @time 2023--12--24--13:45
*/
public interface SDCard {
String readSD();
void writeSD(String msg);
}
/**
* @author LXY
* @desc
* @time 2023--12--24--13:46
*/
public class SDCardImple implements SDCard{
@Override
public String readSD() {
return "SD读取成功,内容是:Hello Word";
}
@Override
public void writeSD(String msg) {
System.out.println("SD存储成功,内容是:"+msg);
}
}
/**
* @author LXY
* @desc 电脑类,但是电脑类只能读取SD卡
* @time 2023--12--24--13:48
*/
public class Computer {
public String readSD(SDCard sdCard){
if (sdCard==null){
throw new NullPointerException("SDCard is not null");
}
return sdCard.readSD();
}
}
/**
* @author LXY
* @desc 类适配器
* @time 2023--12--24--13:50
*/
public class SDAdapterTF extends TFCardImple implements SDCard{
@Override
public String readSD() {
return super.readTF();
}
@Override
public void writeSD(String msg) {
super.writeTF(msg);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--13:52
*/
public class Client {
public static void main(String[] args) {
//实例化电脑
Computer computer=new Computer();
System.out.println("computer.readSD(new SDAdapterTF()) = " + computer.readSD(new SDAdapterTF()));
}
}
/**
* @author LXY
* @desc 类适配器
* @time 2023--12--24--13:50
*/
public class SDAdapterTF implements SDCard{
TFCardImple tfCardImple;
public SDAdapterTF(TFCardImple tfCardImple) {
this.tfCardImple = tfCardImple;
}
@Override
public String readSD() {
return tfCardImple.readTF();
}
@Override
public void writeSD(String msg) {
tfCardImple.writeTF(msg);
}
}
/**
* @author LXY
* @desc 快餐类
* @time 2023--12--24--14:53
*/
public abstract class FastFood {
private float price; //价格
private String desc; //描述
//返回具体的价格
public abstract float cost();
//构造器
public FastFood() {
}
public FastFood(float price, String desc) {
this.price = price;
this.desc = desc;
}
//getset方法
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
/**
* @author LXY
* @desc 炒面
* @time 2023--12--24--14:56
*/
public class FriedNode extends FastFood{
public FriedNode() {
super(15,"炒面");
}
@Override
public float cost() {
return 15;
}
}
/**
* @author LXY
* @desc 炒饭类(10块)
* @time 2023--12--24--14:55
*/
public class FriedRice extends FastFood{
@Override
public float cost() {
return 10;
}
public FriedRice() {
super(10,"扬州炒饭");
}
}
/**
* @author LXY
* @desc 装饰者类
* @time 2023--12--24--14:57
*/
public abstract class Garnish extends FastFood{
//声明快餐变量
private FastFood fastFood;
//有参数构造器
public Garnish(float price, String desc, FastFood fastFood) {
super(price, desc);
this.fastFood = fastFood;
}
//getset
public FastFood getFastFood() {
return fastFood;
}
public void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}
}
/**
* @author LXY
* @desc 鸡蛋类
* @time 2023--12--24--14:59
*/
public class Egg extends Garnish {
public Egg(FastFood fastFood) {
super(1, "鸡蛋", fastFood);
}
@Override
public float cost() {
return getFastFood().cost()+getPrice();
}
@Override
public String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--15:03
*/
public class Client {
public static void main(String[] args) {
FastFood fastFood=new FriedNode();
fastFood=new Egg(fastFood);
System.out.println("您已点"+fastFood.getDesc()+",其价格是"+fastFood.cost());
}
}
静态代理和装饰着的区别
相同点:
开发一份跨平台视频播放器,可以在不同操作系统平台如(Windows,Mac,Linux等)上播放多种格式的视频文件,常见的视频格式包括EMVB,AVI,WMV等,该播放器包含了两个维度,适合使用桥接模式
/**
* @author LXY
* @desc
* @time 2023--12--24--16:14
*/
public class Client {
public static void main(String[] args) {
Windows win=new Windows(new RMVBFile());
win.play("战狼");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:06
*/
public abstract class VideoFile {
abstract void decode(String Fiename);
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:07
*/
public class RMVBFile extends VideoFile{
@Override
void decode(String Fiename) {
System.out.println("RMVBFile正在播放文件:+"+Fiename);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:12
*/
public class Windows extends OperatingSystem{
public Windows(VideoFile videoFile) {
super(videoFile);
}
@Override
void play(String Filename) {
videoFile.decode(Filename);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:09
*/
public abstract class OperatingSystem {
protected VideoFile videoFile;
public OperatingSystem(VideoFile videoFile) {
this.videoFile = videoFile;
}
abstract void play(String Filename);
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:12
*/
public class MAC extends OperatingSystem{
public MAC(VideoFile videoFile) {
super(videoFile);
}
@Override
void play(String Filename) {
videoFile.decode(Filename);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:07
*/
public class AVIFile extends VideoFile{
@Override
void decode(String Fiename) {
System.out.println("AVIFile正在播放文件:+"+Fiename);
}
}
桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统
如:如果现在还有一种视频文件类型wmv,我们只需要在定义一个类实现VIDERFILE接口即可,其他类不需要发生变化
实现细节对客户透明
/**
* @author LXY
* @desc
* @time 2023--12--24--16:45
*/
public class TV {
void on(){
System.out.println("TV on()");
}
void off(){
System.out.println("TV off()");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:45
*/
public class Light {
void on(){
System.out.println("Light on()");
}
void off(){
System.out.println("Light off()");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:45
*/
public class AirCondition {
void on(){
System.out.println("AirCondition on()");
}
void off(){
System.out.println("AirCondition off()");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:47
*/
public class SmartAppliancesFacade {
//做一个聚合操作
Light light;
TV tv;
AirCondition airCondition;
//构造器
public SmartAppliancesFacade() {
light=new Light();
tv=new TV();
airCondition=new AirCondition();
}
public void say(String message){
if (message.equals("关灯")){
on();
}else if (message.equals("开灯")){
off();
}
}
private void off() {
light.off();
tv.off();
airCondition.off();
}
private void on() {
light.on();
tv.on();
airCondition.on();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--16:51
*/
public class Cilent {
public static void main(String[] args) {
SmartAppliancesFacade smartAppliancesFacade=new SmartAppliancesFacade();
smartAppliancesFacade.say("开灯");
}
}
俄罗斯方块,如果在这里每一个方块都是一个对象就需要占据很大的空间,下面用享元模式实现
/**
* @author LXY
* @desc
* @time 2023--12--24--18:35
*/
public abstract class AbstractBox {
abstract String getshape();
public void display(String color){
System.out.println("颜色是"+color);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--18:36
*/
public class IBOX extends AbstractBox{
@Override
String getshape() {
return "IBOX";
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--18:36
*/
public class LBOX extends AbstractBox{
@Override
String getshape() {
return "LBOX";
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--18:36
*/
public class OBOX extends AbstractBox{
@Override
String getshape() {
return "OBOX";
}
}
/**
* @author LXY
* @desc 工厂
* @time 2023--12--24--18:37
*/
public class BoxFactory {
static volatile BoxFactory BOX_FACTORY=new BoxFactory();
//这里当map当做是缓存
private HashMap<String,AbstractBox>map;
//构造器
public BoxFactory() {
map=new HashMap<>();
map.put("L",new LBOX());
map.put("O",new OBOX());
map.put("I",new IBOX());
}
//单例
public static BoxFactory getInstance(){
return BOX_FACTORY;
}
public AbstractBox getBox(String key){
return map.get(key);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--24--18:41
*/
public class Client {
public static void main(String[] args) {
final AbstractBox l = BoxFactory.getInstance().getBox("L");
l.display("Red");
}
}
在面向对象程序设计过程中,程序员常常遇到这样的问题,设计一个系统知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关
例如:去银行办理业务一般要经历以下4个流程:取号,排队,办理具体业务,对银行工作人员进行评分等,其中取号,排队,和对银行工作人员进行评分云业务对每个客户是一样的,可以再父类中实现,但是办理具体业务缺因人而异,它可能是存款,取款,或者转账等,可以延迟到子类实现
定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,是的子类可以不改变算法结构的情况下重定义该算法的某些特定步骤
模板方法(Template Method)模式包含以下主要角色
抽象类(Abstract class):负责给出一个算法的轮廓和骨架,它是由一个模板方法和若干基本方法构成
2.具体方法(Concrete Method):一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承
3.钩子方法(Hook Method)在抽象类中已经实现,包括用于判断的逻辑方法和需要重写子类的空方法两种
一般钩子方法适用于判断的扩机方法,这类方法名一般为isXxx,返回值是boolwan类型
具体子类(Concrete Class):实现了抽象类中所定义的抽象方法和钩子方法,他们是一个顶级逻辑的组成步骤
* @author LXY
* @desc
* @time 2023--12--25--11:26
*/
public abstract class AbstartClass {
public final void cookProcess(){
prouroi(); //倒油
heatoil(); //热油
pouvegetable(); //下菜
pourSauce(); //放调料
fry(); //炒菜
}
public void prouroi(){
System.out.println("倒油");
}
public void heatoil(){
System.out.println("热油");
}
//倒蔬菜是不一样的(一个是下包菜,一个是空心菜)
public abstract void pouvegetable();
//到的调料品是不一样的
public abstract void pourSauce();
public void fry(){
System.out.println("炒菜,炒到熟");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--11:29
*/
public class ConcerateClass_BaoCai extends AbstartClass{
@Override
public void pouvegetable() {
System.out.println("下包菜");
}
@Override
public void pourSauce() {
System.out.println("下辣椒");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--11:29
*/
public class ConcerateClass_CaiXin extends AbstartClass{
@Override
public void pouvegetable() {
System.out.println("下卷心菜");
}
@Override
public void pourSauce() {
System.out.println("下盐");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--11:30
*/
public class Cliet {
public static void main(String[] args) {
ConcerateClass_BaoCai concerateClass_baoCai=new ConcerateClass_BaoCai();
concerateClass_baoCai.cookProcess();
}
}
-优点:
public abstract class InputStream implements Closeable {
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();
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;
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:20
*/
public abstract class Strategy {
public abstract void show();
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:20
*/
public class StartegyA extends Strategy{
@Override
public void show() {
System.out.println("满500减200");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:20
*/
public class StartegyB extends Strategy{
@Override
public void show() {
System.out.println("满一送一");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:20
*/
public class StartegyC extends Strategy{
@Override
public void show() {
System.out.println("满500抽免单");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:21
*/
public class SalesMan {
Strategy strategy;
public SalesMan(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void salesManshow(){
strategy.show();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--14:22
*/
public class Client {
public static void main(String[] args) {
SalesMan salesMan=new SalesMan(new StartegyA());
salesMan.salesManshow();
System.out.println("------------");
salesMan.setStrategy(new StartegyB());
salesMan.salesManshow();
System.out.println("------------");
salesMan.setStrategy(new StartegyC());
salesMan.salesManshow();
}
}
/**
* @author LXY
* @desc 厨师
* @time 2023--12--25--15 :31
*/
public class SenoirCherf {
public void makFood(int num,String footName){
System.out.println("座位号:"+num+"正在做:"+footName);
}
}
/**
* @author LXY
* @desc 订单类
* @time 2023--12--25--15:28
*/
public class Order {
//餐桌号
int daningTable;
//点餐
Map<String,Integer> map=new HashMap<>();
public void setDaningTable(int daningTable) {
this.daningTable = daningTable;
}
public int getDaningTable() {
return daningTable;
}
public Map<String, Integer> getMap() {
return map;
}
public void setMap(Integer num, String name) {
map.put(name,num);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--15:32
*/
public interface Command {
void execute();
}
/**
* @author LXY
* @desc
* @time 2023--12--25--15:33
*/
public class OrderCommand implements Command{
//厨师
SenoirCherf senoirCherf;
Order order; //订单
public OrderCommand(SenoirCherf senoirCherf, Order order) {
this.senoirCherf = senoirCherf;
this.order = order;
}
@Override
public void execute() {
System.out.println("接受到的订单");
final Map<String, Integer> map = order.getMap(); //获取到订单
for (String str : map.keySet()) {
System.out.println("订单来了:菜品是"+str+",数量是:"+map.get(str));
senoirCherf.makFood(order.getDaningTable(),str);
}
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--15:37
*/
public class Waitor {
//多个命令类一个服务员可以发送多个命令
List<Command>Commands=new ArrayList<>();
//载入数据
public void setList(Command command) {
Commands.add(command);
}
void Orderup(){
for (Command command : Commands) {
command.execute();
}
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--15:40
*/
public class Client {
public static void main(String[] args) {
//生成两份订单
Order order1 = new Order();
order1.setDaningTable(1);
order1.setMap(5,"可乐");
order1.setMap(10,"汉堡");
Order order2 = new Order();
order2.setDaningTable(2);
order2.setMap(1,"西红柿炒鸡蛋");
order2.setMap(1,"炒河粉");
//指定厨师
SenoirCherf senoirCherf=new SenoirCherf();
Command command1=new OrderCommand(senoirCherf,order1);
Command command2=new OrderCommand(senoirCherf,order2);
Waitor waitor=new Waitor();
waitor.setList(command1);
waitor.setList(command2);
waitor.Orderup(); //开始
}
}
结构:朱泽连模式主要包含以下角色:
/**
* @author LXY
* @desc 请假条类
* @time 2023--12--25--16:40
*/
public class LeavRepuest {
private String name;
private Integer num;
private String content;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
/**
* @author LXY
* @desc 抽象的
* @time 2023--12--25--16:34
*/
public abstract class Hander {
//定义常量用于判断请假时间
protected final static Integer NUM_ONE=1;
protected final static Integer NUM_THREE=3;
protected final static Integer NUM_SEVEN=7;
Hander nexHand;
private Integer numStart; //能管理的开始时间
private Integer numEnd; //能管理的最终时间
//子类需要重写构造器,传递给父类自己能审批的时间
public Hander(Integer numStart, Integer numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}
public void setNexHand(Hander nexHand) {
this.nexHand = nexHand;
}
//需要子类重写该方法,这是一个审批方法
public abstract void setNexHand(LeavRepuest leavRepuest);
//提交
public void sumbit(LeavRepuest leavRepuest){
if (leavRepuest.getNum()==null)
throw new NullPointerException("请假时间不能为空");
if ((leavRepuest.getNum()>this.numStart)&&(leavRepuest.getNum()<=this.numEnd)){
setNexHand(leavRepuest); //开始请假
}else {
this.nexHand.sumbit(leavRepuest); //如果自己没权限就去链上寻找
}
}
}
/**
* @author LXY
* @desc 总经理
* @time 2023--12--25--16:46
*/
public class GeneralManager extends Hander{
public GeneralManager() {
super(NUM_THREE, NUM_SEVEN);
}
@Override
public void setNexHand(LeavRepuest leavRepuest) {
System.out.println("总经理请假同意:请假人姓名-"+leavRepuest.getName()+",请假天数:"+leavRepuest.getNum()+",请假理由:"+leavRepuest.getContent());
}
}
/**
* @author LXY
* @desc 组长
* @time 2023--12--25--16:46
*/
public class GroupLeader extends Hander{
public GroupLeader() {
super(0, NUM_ONE);
}
@Override
public void setNexHand(LeavRepuest leavRepuest) {
System.out.println("小组长请假同意:请假人姓名-"+leavRepuest.getName()+",请假天数:"+leavRepuest.getNum()+",请假理由:"+leavRepuest.getContent());
}
}
/**
* @author LXY
* @desc 经理
* @time 2023--12--25--16:46
*/
public class Manager extends Hander{
public Manager() {
super(NUM_ONE, NUM_THREE);
}
@Override
public void setNexHand(LeavRepuest leavRepuest) {
System.out.println("经理请假同意:请假人姓名-"+leavRepuest.getName()+",请假天数:"+leavRepuest.getNum()+",请假理由:"+leavRepuest.getContent());
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--16:51
*/
public class Client {
private static Hander groupLeader = null;
static {
//组长
groupLeader =new GroupLeader();
//副总经理
Hander manager=new Manager();
//总经理
Hander generalManager=new GeneralManager();
//绑定职责链
groupLeader.setNexHand(manager);
manager.setNexHand(generalManager);
}
public static void main(String[] args) {
LeavRepuest leavRepuest = new LeavRepuest();
leavRepuest.setNum(2);
leavRepuest.setContent("支原体感染");
leavRepuest.setName("张三");
//因为员工只认识自己的上级,所以就只能找自己的上级,组长处理不了继续往上找
groupLeader.sumbit(leavRepuest);
}
}
优点
降低了对象之间的耦合度
该模式降低了请求发送你这和接受者的耦合度
增强了系统的可扩展性
可以根据需要增加新的请求处理类,满足开闭原则
增强了给对象指派职责的灵活性
当工作流程发生变化,可以懂爱的改变链内的成员或者修改它们的次序,也可以动态的新增或者删除责任
责任链简化了对象之间的连接
一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的if或者if…else语句
责任分担
每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的职责范围,符合单一职责原则
缺点:
不能保证每个请求一定被处理,由于一个请求没有明确的接受者,所以不能保证它一定会被处理,该请求可能传递发哦链的末端都得不到处理
队比较长的则热念,请求的处理可能设计多个对象,系统性能会受到一定的影响
在JAVA中的过滤器链和设计模式的职责从某种程度上是一样的
概述,通过按钮来控制一个电梯的状态,一个电梯有关门状态,开门状态,停止状态,运行状态,每一种状态都可以改变,都有可能根据其他状态来更新处理,例如:如果电梯门处于运行状态,就不能进行开门操作,如果电梯门是停止状态就可以执行开门操作
状态模式,以下代码略微有点不好理解,可以理解为在Client中,客户首先传递的是Open模式(数据源),
然后去调用Open状态下的open方法,打印,然后调用Open模式下的close方法,但是close方法需要在close模式下才能打印,只能通过 context.setLiftState(context.closeIngState); 去修改之前传递的open模式,这样数据源就变成了close模式
- 核心代码
public void setLiftState(LiftState liftState){
this.liftState=liftState;
liftState.setContext(this); //将自己传给LiftState对象的Context以供子类使用,这样就做到了数据地址不变数据一样就可以实现在子类切换数据源了
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18: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 start();
public abstract void stop();
}
/**
* @author LXY
* @desc 上下文类
* @time 2023--12--25--18:46
*/
public class Context {
//实例化四个状态
public OpenIngState openIngState=new OpenIngState();
public CloseIngState closeIngState=new CloseIngState();
public RunIngState runIngState=new RunIngState();
public StopIngState stopIngState=new StopIngState();
private LiftState liftState;
public void setLiftState(LiftState liftState){
this.liftState=liftState;
liftState.setContext(this);
}
public void open() {
this.liftState.open();
}
public void close() {
this.liftState.close();
}
public void start() {
this.liftState.start();
}
public void stop() {
this.liftState.stop();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18:49
*/
public class OpenIngState extends LiftState{
@Override
public void open() {
System.out.println("电梯门已开");
}
@Override
public void close() {
context.setLiftState(context.closeIngState);
context.close();
}
@Override
public void start() {
//电梯门开着不能启动
}
@Override
public void stop() {
//电梯门开着不能停止运行
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18:49
*/
public class RunIngState extends LiftState{
@Override
public void open() {
//整在运行不能开门
}
@Override
public void close() {
}
@Override
public void start() {
System.out.println("正在运行");
}
@Override
public void stop() {
context.setLiftState(context.stopIngState);
context.stop();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18:49
*/
public class StopIngState extends LiftState{
@Override
public void open() {
context.setLiftState(context.openIngState);
context.open();
}
@Override
public void close() {
context.setLiftState(context.closeIngState);
context.close();
}
@Override
public void start() {
context.setLiftState(context.runIngState);
context.start();
}
@Override
public void stop() {
System.out.println("电梯已经停止");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18:49
*/
public class CloseIngState extends LiftState{
@Override
public void open() {
context.setLiftState(context.openIngState);
context.open();
}
@Override
public void close() {
System.out.println("电梯门已关");
}
@Override
public void start() {
context.setLiftState(context.runIngState);
context.start();
}
@Override
public void stop() {
context.setLiftState(context.stopIngState);
context.stop();
}
}
/**
* @author LXY
* @desc
* @time 2023--12--25--18:59
*/
public class Client {
public static void main(String[] args) {
Context context=new Context();
// context.setLiftState(new OpenIngState());
// context.setLiftState(new CloseIngState());
context.setLiftState(new RunIngState());
context.open();
context.close();
context.start();
context.stop();
}
}
/**
* @author LXY
* @desc 抽象的被观察者
* @time 2023--12--26--10:09
*/
public abstract class Subject {
//添加方法
abstract void attach(ObjectServer server);
//删除方法
abstract void detach(ObjectServer server);
//发送消息
abstract void notify(String message);
}
/**
* @author LXY
* @desc
* @time 2023--12--26--10:12
*/
public class SubscriptionSubject extends Subject{
//观察者集合
List<ObjectServer>serverList;
public SubscriptionSubject() {
serverList=new ArrayList<>();
}
@Override
void attach(ObjectServer server) {
serverList.add(server);
}
@Override
void detach(ObjectServer server) {
serverList.remove(server);
}
@Override
void notify(String message) {
//给每一个观察者发送消息
for (ObjectServer objectServer : serverList) {
objectServer.update(message);
}
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--10:10
*/
public interface ObjectServer {
void update(String mess);
}
/**
* @author LXY
* @desc
* @time 2023--12--26--10:14
*/
public class WeixinUser implements ObjectServer{
String name;
public WeixinUser(String name) {
this.name = name;
}
@Override
public void update(String mes) {
System.out.println(name+"接收到了消息:"+mes);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--10:15
*/
public class Client {
public static void main(String[] args) {
//实例化微信用户
SubscriptionSubject subject = new SubscriptionSubject();
subject.attach(new WeixinUser("孙悟空"));
subject.attach(new WeixinUser("杨戬"));
subject.attach(new WeixinUser("哪吒"));
subject.notify("您关注的天庭趣事更新了");
}
}
`
/**
* @author LXY
* @desc 学生实体类
* @time 2023--12--26--11:22
*/
public class Student {
//学号,姓名
private String name;
private String num;
public Student(String name, String num) {
this.name = name;
this.num = num;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", num='" + num + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}
/**
* @author LXY
* @desc 迭代器接口
* @time 2023--12--26--11:24
*/
public interface StudentItetator {
//用来判断有没有下一个元素
boolean hasNex();
Student next();
}
/**
* @author LXY
* @desc 迭代器接口的实现
* @time 2023--12--26--11:25
*/
public class StudentItetatorImple implements StudentItetator{
//学生存储对象
List<Student>studentList;
public StudentItetatorImple(List<Student> studentList) {
this.studentList = studentList;
}
private int position=0; //定义计数器
@Override
public boolean hasNex() {
return position<studentList.size();
}
@Override
public Student next() {
//拿到数据
Student student = studentList.get(position);
position++; //计数器+1
return student;
}
}
/**
* @author LXY
* @desc 对学生的功能操作的获取学生迭代器
* @time 2023--12--26--11:23
*/
public interface StudentAggregate {
void addStudent(Student s);
void removeStudent(Student s);
StudentItetator getStudentItetator();
}
/**
* @author LXY
* @desc
* @time 2023--12--26--11:29
*/
public class StudentAggregateImple implements StudentAggregate {
private List<Student>studentList;
public StudentAggregateImple() {
this.studentList = new ArrayList<>();
}
@Override
public void addStudent(Student s) {
studentList.add(s);
}
@Override
public void removeStudent(Student s) {
studentList.remove(s);
}
@Override
public StudentItetator getStudentItetator() {
return new StudentItetatorImple(studentList);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--11:32
*/
public class Client {
public static void main(String[] args) {
StudentAggregateImple studentAggregateImple = new StudentAggregateImple();
studentAggregateImple.addStudent(new Student("张三","001"));
studentAggregateImple.addStudent(new Student("李四","008"));
studentAggregateImple.addStudent(new Student("张飞","006"));
final StudentItetator studentItetator = studentAggregateImple.getStudentItetator();
while (studentItetator.hasNex()){
final Student next = studentItetator.next();
System.out.println(next);
}
}}
使用场景
当需要为聚合对象提供多种遍历方式时。
当需要为遍历不同的聚合结构提供一个统一接口时
当访问一个聚合对象的内容而无需暴露其内部细节的表示时
/**
* @author LXY
* @desc
* @time 2023--12--26--14:53
*/
public interface Aminal {
void accept(Persion p);
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:54
*/
public class Cat implements Aminal{
@Override
public void accept(Persion p) {
p.feed(this);
System.out.println("喵喵---");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:54
*/
public class Dog implements Aminal{
@Override
public void accept(Persion p) {
p.feed(this);
System.out.println("汪汪汪");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:53
*/
public interface Persion {
void feed(Cat cat);
void feed(Dog dog);
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:56
*/
public class Someone implements Persion{
@Override
public void feed(Cat cat) {
System.out.println(" Someone 喂猫");
}
@Override
public void feed(Dog dog) {
System.out.println(" Someone 喂狗 ");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:55
*/
public class Owner implements Persion{
@Override
public void feed(Cat cat) {
System.out.println(" Owner 喂猫");
}
@Override
public void feed(Dog dog) {
System.out.println(" Owner 喂狗 ");
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--14:58
*/
public class Home {
//存错多个动物
List<Aminal>aminalList=new ArrayList<Aminal>();
public void add(Aminal aminal){
aminalList.add(aminal);
}
public void action(Persion persion){
for (Aminal aminal : aminalList) {
aminal.accept(persion);
}
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--15:00
*/
public class Client {
public static void main(String[] args) {
Home home=new Home();
home.add(new Cat());
home.add(new Dog());
home.action(new Someone());
}
}
例:【挑战游戏Boss】
游戏中的某个场景,一游戏角色有生命力,攻击力,防御力等数据,在打Boss前后是不一样的,我们允许玩家如果感觉与Boss决定的效果不理想可以让游戏恢复到决斗之前的状态
/**
* @author LXY
* @desc 角色类
* @time 2023--12--26--16:06
*/
public class GanmeRole {
private int Vit; //生命力
private int atk; //攻击力
private int def; //防御力
//初始化状态
void initState(){
this.Vit=100;
this.atk=100;
this.def=100;
}
//和boss进行战斗
void fight(){
this.Vit=0;
this.atk=120;
this.def=30;
}
//保存备忘录
RoleStateMemento savaState(){
return new RoleStateMemento(this.Vit,this.atk,this.def);
}
//备忘录的数据进行恢复
void recoverState(RoleStateMemento roleStateMemento){
this.setAtk(roleStateMemento.getAtk());
this.setDef(roleStateMemento.getDef());
this.setVit(roleStateMemento.getVit());
}
public int getVit() {
return Vit;
}
public void setVit(int vit) {
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 GanmeRole() {
}
public GanmeRole(int vit, int atk, int def) {
Vit = vit;
this.atk = atk;
this.def = def;
}
@Override
public String toString() {
return "GanmeRole{" +
"Vit=" + Vit +
", atk=" + atk +
", def=" + def +
'}';
}
}
/**
* @author LXY
* @desc 备忘录,可以通过我来进行数据的恢复
* @time 2023--12--26--16:09
*/
public class RoleStateMemento {
private int Vit; //生命力
private int atk; //攻击力
private int def; //防御力
public RoleStateMemento() {
}
public RoleStateMemento(int vit, int atk, int def) {
Vit = vit;
this.atk = atk;
this.def = def;
}
public int getVit() {
return Vit;
}
public void setVit(int vit) {
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;
}
}
/**
* @author LXY
* @desc 游戏管理者对象
* @time 2023--12--26--16:14
*/
public class RoleStateCaretaker {
RoleStateMemento roleStateMemento;
public RoleStateMemento getRoleStateMemento() {
return roleStateMemento;
}
public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
this.roleStateMemento = roleStateMemento;
}
public RoleStateCaretaker(RoleStateMemento roleStateMemento) {
this.roleStateMemento = roleStateMemento;
}
public RoleStateCaretaker() {
}
/**
* @author LXY
* @desc
* @time 2023--12--26--16:14
*/
public class Cliet {
public static void main(String[] args) {
GanmeRole ganmeRole=new GanmeRole(); //初始化角色类
System.out.println("----------战斗开始--------");
ganmeRole.initState();
System.out.println(ganmeRole.toString());
//创建游戏管理者对象
RoleStateCaretaker roleStateCaretaker=new RoleStateCaretaker();
//战斗开始的时候做一下备份 这是备份出来的数据
roleStateCaretaker.setRoleStateMemento( ganmeRole.savaState());
System.out.println("-----------战斗结束---------");
ganmeRole.fight();
System.out.println(ganmeRole.toString());
System.out.println("------------恢复数据--------");
ganmeRole.recoverState(roleStateCaretaker.getRoleStateMemento());
System.out.println(ganmeRole.toString());
}
}
/**
* @author LXY
* @desc 备忘录接口,对外提供的窄接口
* @time 2023--12--26--16:27
*/
public interface Memento {
}
/**
* @author LXY
* @desc 角色类
* @time 2023--12--26--16:06
*/
public class GanmeRole {
private int Vit; //生命力
private int atk; //攻击力
private int def; //防御力
//初始化状态
void initState(){
this.Vit=100;
this.atk=100;
this.def=100;
}
//和boss进行战斗
void fight(){
this.Vit=0;
this.atk=120;
this.def=30;
}
//保存备忘录
RoleStateMemento savaState(){
return new RoleStateMemento(this.Vit,this.atk,this.def);
}
//备忘录的数据进行恢复
void recoverState(Memento memento){
RoleStateMemento roleStateMemento= (RoleStateMemento) memento;
this.setAtk(roleStateMemento.getAtk());
this.setDef(roleStateMemento.getDef());
this.setVit(roleStateMemento.getVit());
}
public int getVit() {
return Vit;
}
public void setVit(int vit) {
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 GanmeRole() {
}
public GanmeRole(int vit, int atk, int def) {
Vit = vit;
this.atk = atk;
this.def = def;
}
@Override
public String toString() {
return "GanmeRole{" +
"Vit=" + Vit +
", atk=" + atk +
", def=" + def +
'}';
}
public class RoleStateMemento implements Memento{
private int Vit; //生命力
private int atk; //攻击力
private int def; //防御力
public RoleStateMemento() {
}
public RoleStateMemento(int vit, int atk, int def) {
Vit = vit;
this.atk = atk;
this.def = def;
}
public int getVit() {
return Vit;
}
public void setVit(int vit) {
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;
}
}
}
/**
* @author LXY
* @desc 游戏管理者对象
* @time 2023--12--26--16:14
*/
public class RoleStateCaretaker {
Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--16:14
*/
public class Cliet {
public static void main(String[] args) {
com.rj.jand.patten.memorandum.BlackMemoradum.GanmeRole ganmeRole=new GanmeRole(); //初始化角色类
System.out.println("----------战斗开始--------");
ganmeRole.initState();
System.out.println(ganmeRole.toString());
final RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
//战斗开始的时候做一下备份 这是备份出来的数据
roleStateCaretaker.setMemento( ganmeRole.savaState());
System.out.println("-----------战斗结束---------");
ganmeRole.fight();
System.out.println(ganmeRole.toString());
System.out.println("------------恢复数据--------");
ganmeRole.recoverState(roleStateCaretaker.getMemento());
System.out.println(ganmeRole.toString());
}
需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能,
需要提供一个可回滚操作的场景,如word,PS,idea等软件的撤销功能,还有数据库中事务的操作
/**
* @author LXY
* @desc
* @time 2023--12--26--17:04
*/
public interface AbstractEcpresssion {
int interpret(Context c);
}
/**
* @author LXY
* @desc
* @time 2023--12--26--17:06
*/
public class Plus implements AbstractEcpresssion{
private AbstractEcpresssion left;
private AbstractEcpresssion right;
public Plus(AbstractEcpresssion left, AbstractEcpresssion right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context c) {
//相加
return left.interpret(c)+right.interpret(c);
}
}
/**
* @author LXY
* @desc 减法
* @time 2023--12--26--17:06
*/
public class Minus implements AbstractEcpresssion{
private AbstractEcpresssion left;
private AbstractEcpresssion right;
public Minus(AbstractEcpresssion left, AbstractEcpresssion right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Context c) {
//相加
return left.interpret(c)-right.interpret(c);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--17:05
*/
public class Variable implements AbstractEcpresssion{
String name;
public Variable(String name) {
this.name = name;
}
@Override
public int interpret(Context c) {
return c.getvalue(this);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--17:05
*/
public class Context {
//定义存储Variable
Map<Variable,Integer>map=new HashMap<>();
public void assign(Variable val,Integer value){
map.put(val,value);
}
public int getvalue(Variable v){
return map.get(v);
}
}
/**
* @author LXY
* @desc
* @time 2023--12--26--17:11
*/
public class Client {
public static void main(String[] args) {
Variable a=new Variable("a");
Variable b=new Variable("b");
Variable c=new Variable("c");
Variable d=new Variable("d");
Context context=new Context();
context.assign(a,1);
context.assign(b,2);
context.assign(c,3);
context.assign(d,4);
//简单加减法 1+2
// AbstractEcpresssion abstractEcpresssion=new Plus(a,b);
//1+2-3
AbstractEcpresssion abstractEcpresssion=new Plus(a,new Minus(b,c));
System.out.println("abstractEcpresssion.interpret(context) = " + abstractEcpresssion.interpret(context));
}
}
优点:易于改变和扩展文法
由于在解释器模式中使用类来表示文言的文法规则,因此可以通过继承机制来改变或扩展文法,每一条文法负责都可以表示是一个类,因此可以方便的实现一个简单的语言
实现文法比较容易
在抽象语法书中每一个表达式节点类的实现方式都是相似的,这些类的代码编写的都不会特别复杂
增加新的解释表达式较为方便
如果用户需要增加新的解释表达式只需要对应增加一个新的总结福表达式或者非终结符表达式类,原有表达式类大马无需修改,符合开闭原则
缺点:
对于复杂文法难以维护
在解释器模式中,每一条规则至少需要定义一个类,因此如果一个预压包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护
执行效率低
由于在解释器模式使用了大量的循环和递归调用,因此在解释较为复杂的句子时速度很慢,而代码的调试过程也比较麻烦