****************************************************************************************************************************************************************************
1、设计模式概述 【1】前辈们对代码开发经验的总结,解决问题的套路。是用来提高代码可复用性、可读性、可维护性、健壮性、安全性的解决方案。 【2】GoF23-23种设计模式。设计模式的本质是面向对象设计原则的实际运用。封装、继承、多态。代码的复用性、扩展性。 【3】模式名称、问题、解决方案、效果。一种思维、一种态度、一种进步 【4】创建型模式:单列模式、工厂模式、抽象工厂模式、建造者模式、原型模式。 结构性模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式,享元模式、代理模式。 行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
****************************************************************************************************************************************************************************
2、OOP七大原则 【1】开闭原则:对扩展开放,对修改关闭。里氏替换原则:子类可以扩展,但是不要覆盖父类的东西。依赖倒置原则:面向接口编程。单一职责原则:一个类不要太复杂,原子性。 接口隔离原则:为各个类建立专用接口。迪米特法则:只与直接朋友交谈,不跟陌生人说话。合成复用原则:尽量使用组合或聚合,而少使用继承来实现,A类为B类成员变量+构造方法。
****************************************************************************************************************************************************************************
3、单例模式 【1】上来就创建可能会浪费空间。懒汉式、饿汉式 package com.day.pojo; // 饿汉方式 public class Hungry { // 直接创建对象 private final static Hungry hungry = new Hungry(); // 私有化构造方法 private Hungry() { } public static Hungry getInstance() { return hungry; } } ***************************************懒汉式 package com.day.pojo; // 懒汉式 ; 单线程确实是可以的,但是多线程不行 public class LazyMan { private static LazyMan lazyMan; private LazyMan() { System.out.println(Thread.currentThread().getName()); } public static LazyMan getInstance() { if (lazyMan == null) { lazyMan = new LazyMan(); } return lazyMan; } } ***************************************多线层会有10个被创建 package com.day; import com.day.pojo.LazyMan; public class DayApplication { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { LazyMan.getInstance(); }).start(); } } } ****************************所以要加锁,双重检测锁,就解决了多线程下只会被new一次的问题 package com.day.pojo; // 懒汉式 ; 单线程确实是可以的,但是多线程不行 public class LazyMan { private static LazyMan lazyMan; private LazyMan() { System.out.println(Thread.currentThread().getName()); } public static LazyMan getInstance() { // 加锁 if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); } } } return lazyMan; } } ******************************** package com.day.pojo; // 懒汉式 ; 单线程确实是可以的,但是多线程不行 public class LazyMan { private volatile static LazyMan lazyMan; // 保证变量指向空间时,但是还没有调用构造方法的问题被解决 private LazyMan() { System.out.println(Thread.currentThread().getName()); } public static LazyMan getInstance() { // 加锁 if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); } } } return lazyMan; } } 【2】静态内部类实现 package com.day; import com.day.pojo.LazyMan; import java.lang.reflect.Constructor; public class DayApplication { public static void main(String[] args) throws Exception { // 反射破坏了单例模式 LazyMan instance = LazyMan.getInstance(); Constructor<LazyMan> constructor = LazyMan.class.getDeclaredConstructor(null); constructor.setAccessible(true); LazyMan notValid = constructor.newInstance(); // 这两个不同就是破坏了 System.out.println(instance); System.out.println(notValid); } } ******************************* 加保护机制 package com.day.pojo; // 懒汉式 ; 单线程确实是可以的,但是多线程不行 public class LazyMan { private volatile static LazyMan lazyMan; // 保证变量指向空间时,但是还没有调用构造方法的问题被解决 private LazyMan() { synchronized (LazyMan.class) { if (lazyMan != null) { throw new RuntimeException("不用试图反射破坏异常"); } } System.out.println(Thread.currentThread().getName()); } public static LazyMan getInstance() { // 加锁 if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); } } } return lazyMan; } } ****************************万物归于简单 用flag监控只能监控一次 package com.day.pojo; // 懒汉式 ; 单线程确实是可以的,但是多线程不行 public class LazyMan { private volatile static LazyMan lazyMan; // 保证变量指向空间时,但是还没有调用构造方法的问题被解决 private static boolean myProtectFlag = true; private LazyMan() { synchronized (LazyMan.class) { if (lazyMan != null) { throw new RuntimeException("不用试图反射破坏异常"); } } if (!myProtectFlag) { throw new RuntimeException("对象已经实例化一次,多次实例化非法"); } myProtectFlag = false; System.out.println(Thread.currentThread().getName()); } public static LazyMan getInstance() { // 加锁 if (lazyMan == null) { synchronized (LazyMan.class) { if (lazyMan == null) { lazyMan = new LazyMan(); } } } return lazyMan; } } ***************************黑白之间的攻防战... 【3】枚举本身也是一个class类 javap -p EnumSingle.class 反编译class命令。工具包jad.exe package com.day.pojo; // 枚举 public enum EnumSingle { INSTANCE; public EnumSingle getInstance() { return INSTANCE; } } **************************枚举类基础知识。定义一组常量使用枚举类。可以当做单例模式的实现。 JDK1.5之前,用private final String seasonName="秋天"; package com.day.pojo; public class MyBefore { private final String seasonName; private final String seasonDesc; private MyBefore(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public static final MyBefore SPRING = new MyBefore("春天", "春暖花开"); public static final MyBefore SUMMER = new MyBefore("夏天", "夏日炎炎"); public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } } ************************** package com.day; import com.day.pojo.MyBefore; public class DayApplication { public static void main(String[] args) throws Exception { MyBefore spring = MyBefore.SPRING; System.out.println(spring.getSeasonName()); } } *****************************JDK 1.5之后 package com.day.pojo; public enum MyEnum { // 罗列枚举项 SPRING("春天", "春暖花开"), SUMMER("夏天", "夏日炎炎"); private final String seasonName; private final String seasonDesc; private MyEnum(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } } ************************ package com.day; import com.day.pojo.MyEnum; public class DayApplication { public static void main(String[] args) throws Exception { MyEnum SPRING = MyEnum.SPRING; System.out.println(SPRING.getSeasonName()); } }
****************************************************************************************************************************************************************************
4、工厂模式 【1】不用new对象,简单工厂模式、工厂方法模式。满足的原则:开闭原则、依赖倒转原则、迪米特法则。调用者与实现类解耦。 package com.day.pojo; public interface Car { void name(); } ************************** package com.day.pojo; public class ChinaCar implements Car { @Override public void name() { System.out.println("中国造的车..."); } } ************************** package com.day.pojo; public class AmericanCar implements Car { @Override public void name() { System.out.println("美国造的车..."); } } ************************** package com.day.pojo; // 静态工厂模式,如果不修改代码,不方便扩展 public class CarFactory { public static Car getCar(String car) { if (car.equals("中国")) { return new ChinaCar(); } else if (car.equals("美国")) { return new AmericanCar(); } else { return null; } } } ************************** package com.day; import com.day.pojo.AmericanCar; import com.day.pojo.Car; import com.day.pojo.CarFactory; import com.day.pojo.ChinaCar; public class DayApplication { public static void main(String[] args) throws Exception { /* Car chinaCar = new ChinaCar(); Car americanCar = new AmericanCar();*/ Car chinaCar = CarFactory.getCar("中国"); Car americanCar = CarFactory.getCar("美国"); chinaCar.name(); americanCar.name(); } } ************************** 【2】感觉类变多了...多了一个车的工厂接口,每多一个车,就多一个车工厂实现车的工厂接口。结论:简单工厂更实用、简单
****************************************************************************************************************************************************************************
5、抽象工厂模式 【1】生产工厂的工厂。根据不同的业务来写。对于稳定的业务,还是很强大的。
****************************************************************************************************************************************************************************
6、建造者模式 【1】创建者模式:提供了创建对象的最佳方式。 package com.day.build; // 抽象的建造者 public abstract class Builder { abstract void build_1(); abstract void build_2(); abstract void build_3(); abstract void build_4(); abstract Product getProduct(); } ************************************** package com.day.build; public class Worker extends Builder { private Product product; public Worker() { product = new Product(); } @Override void build_1() { product.setBuild_1("地基"); System.out.println("地基建造完毕"); } @Override void build_2() { product.setBuild_2("钢筋"); System.out.println("钢筋建造完毕"); } @Override void build_3() { product.setBuild_3("电线"); System.out.println("电线建造完毕"); } @Override void build_4() { product.setBuild_4("粉刷"); System.out.println("粉刷完毕"); } @Override Product getProduct() { return product; } } *********************************************** package com.day.build; public class Product { private String build_1; private String build_2; private String build_3; private String build_4; @Override public String toString() { return "Product{" + "build_1='" + build_1 + ''' + ", build_2='" + build_2 + ''' + ", build_3='" + build_3 + ''' + ", build_4='" + build_4 + ''' + '}'; } public String getBuild_1() { return build_1; } public void setBuild_1(String build_1) { this.build_1 = build_1; } public String getBuild_2() { return build_2; } public void setBuild_2(String build_2) { this.build_2 = build_2; } public String getBuild_3() { return build_3; } public void setBuild_3(String build_3) { this.build_3 = build_3; } public String getBuild_4() { return build_4; } public void setBuild_4(String build_4) { this.build_4 = build_4; } } ********************************* package com.day.build; // 指挥 public class Director { public Product build(Builder builder) { builder.build_1(); builder.build_2(); builder.build_3(); builder.build_4(); return builder.getProduct(); } } ******************************************* package com.day; import com.day.build.Director; import com.day.build.Product; import com.day.build.Worker; public class DayApplication { public static void main(String[] args) throws Exception { // 指挥 Director director = new Director(); Product product = director.build(new Worker()); System.out.println(product); } } 【2】客户自己的搭配 package com.day.build; // 抽象的建造者 public abstract class Builder { public abstract Builder build_1(String msg); public abstract Builder build_2(String msg); public abstract Builder build_3(String msg); public abstract Builder build_4(String msg); public abstract Product getProduct(); } ************************ package com.day.build; public class Product { private String build_1 = "地基"; private String build_2 = "钢筋"; private String build_3 = "电线"; private String build_4 = "粉刷"; public String getBuild_1() { return build_1; } public void setBuild_1(String build_1) { this.build_1 = build_1; } public String getBuild_2() { return build_2; } public void setBuild_2(String build_2) { this.build_2 = build_2; } public String getBuild_3() { return build_3; } public void setBuild_3(String build_3) { this.build_3 = build_3; } public String getBuild_4() { return build_4; } public void setBuild_4(String build_4) { this.build_4 = build_4; } @Override public String toString() { return "Product{" + "build_1='" + build_1 + ''' + ", build_2='" + build_2 + ''' + ", build_3='" + build_3 + ''' + ", build_4='" + build_4 + ''' + '}'; } } ****************************** package com.day.build; public class Worker extends Builder { private Product product; public Worker() { product = new Product(); } @Override public Builder build_1(String msg) { product.setBuild_1(msg); System.out.println(msg + "建造完毕"); return this; } @Override public Builder build_2(String msg) { product.setBuild_2(msg); System.out.println(msg + "建造完毕"); return this; } @Override public Builder build_3(String msg) { product.setBuild_3(msg); System.out.println(msg + "建造完毕"); return this; } @Override public Builder build_4(String msg) { product.setBuild_4(msg); System.out.println(msg + "建造完毕"); return this; } @Override public Product getProduct() { return product; } } ********************************* package com.day; import com.day.build.Product; import com.day.build.Worker; public class DayApplication { public static void main(String[] args) throws Exception { // 服务员 Worker worker = new Worker(); Product product = worker.build_1("可乐").build_2("鸡翅").getProduct(); System.out.println(product); } }
****************************************************************************************************************************************************************************
7、原型模式 【1】克隆:Copy。实际中达到提效的目的。 package com.day.prototype; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; // 复制UP主。视频的类 @Data @NoArgsConstructor // 无参构造 public class Video implements Cloneable { private String name; private Date createTime; // 有参构造 public Video(String name, Date createTime) { this.name = name; this.createTime = createTime; } @Override public Object clone() throws CloneNotSupportedException { Object object = super.clone(); Video video = (Video) object; // 克隆他的属性 video.createTime = (Date) this.createTime.clone(); // 这个可以实现深克隆 return object; } } ************************************** package com.day; import com.day.prototype.Video; import java.util.Date; public class DayApplication { public static void main(String[] args) throws Exception { Date date = new Date(); Video video_1 = new Video("纠错大队长", date); System.out.println(video_1 + "---" + video_1.hashCode()); // 克隆(浅克隆) Video video_2 = (Video) video_1.clone(); // video_2 = video_1; // video_2.setName("内容审核"); date.setTime(123456); System.out.println(video_1 + "---" + video_1.hashCode()); System.out.println(video_2 + "---" + video_1.hashCode()); // 深克隆 // 修改代码后就不会时间改变都改变了 } }
****************************************************************************************************************************************************************************
8、适配器模式 【1】创建式模式已经学完。现在开始结构型模式。 【2】USB网线转换器(适配器的思想) package com.day.adapter; import com.day.service.NetToUsb; // 客户端类 public class Computer { public void net(NetToUsb netToUsb) { // 上网实现,找一个转接 netToUsb.handleRequest(); } } ************************* package com.day.adapter; // 网线 public class Adapter { public void request() { System.out.println("连接网线上网..."); } } ****************************** package com.day.service; public interface NetToUsb { // 处理请求 public void handleRequest(); } ******************************* package com.day.service.imp; import com.day.adapter.Adapter; import com.day.service.NetToUsb; // 1 继承 // 2 组合 public class NetToUsbImp extends Adapter implements NetToUsb { @Override public void handleRequest() { super.request(); System.out.println("可以上网了..."); } } 【3】使用组合的方式(单继承局限性太大了,优先使用组合的方式) package com.day.service.imp; import com.day.adapter.Adapter; import com.day.service.NetToUsb; // 1 继承 // 2 组合 public class NetToUsbImp implements NetToUsb { private Adapter adapter; public NetToUsbImp(Adapter adapter) { this.adapter = adapter; } @Override public void handleRequest() { adapter.request(); System.out.println("可以上网了..."); } } ******************************** package com.day; import com.day.adapter.Adapter; import com.day.adapter.Computer; import com.day.service.imp.NetToUsbImp; public class DayApplication { public static void main(String[] args) throws Exception { // 电脑 适配器 网线 Computer computer = new Computer(); Adapter adapter = new Adapter(); NetToUsbImp netToUsbImp = new NetToUsbImp(adapter);// 这里就实现了组合 这是个最高效的方式 computer.net(netToUsbImp); } }
****************************************************************************************************************************************************************************
9、桥接模式 【1】将抽象的部分与它的实现分离开。通过一座桥把他们连接起来 package com.day.service; public interface Brand { void info(); } ***************************** package com.day.service.imp; import com.day.service.Brand; import lombok.Data; @Data public class LenovoImp implements Brand { @Override public void info() { System.out.println("联想"); } } ***************************** package com.day.service.imp; import com.day.service.Brand; import lombok.Data; @Data public class AppleImp implements Brand { @Override public void info() { System.out.println("苹果"); } } ***************************** package com.day.service; import lombok.Data; @Data public abstract class Computer { // 组合品牌 protected Brand brand; // 这里是一座桥............................................................ public Computer(Brand brand) { this.brand = brand; } public void computerInfo() { brand.info(); } } ***************************** package com.day.service.imp; import com.day.service.Brand; import com.day.service.Computer; public class Desktop extends Computer { public Desktop(Brand brand) { super(brand); } @Override public void computerInfo() { super.computerInfo(); System.out.println("台式机"); } } ***************************** package com.day.service.imp; import com.day.service.Brand; import com.day.service.Computer; public class Laptop extends Computer { public Laptop(Brand brand) { super(brand); } @Override public void computerInfo() { super.computerInfo(); System.out.println("笔记本"); } } ***************************** package com.day; import com.day.service.Brand; import com.day.service.Computer; import com.day.service.imp.AppleImp; import com.day.service.imp.Desktop; import com.day.service.imp.Laptop; import com.day.service.imp.LenovoImp; public class DayApplication { public static void main(String[] args) throws Exception { Computer computer = new Laptop(new AppleImp()); computer.computerInfo(); Computer computer2 = new Desktop(new LenovoImp()); computer2.computerInfo(); } } 【2】桥接模式优于多继承。里面会用到抽象类的(这里抽象类的用武之地)。
****************************************************************************************************************************************************************************
10、静态代理模式 【1】中介。代理模式就是SpringAOP的底层。分类:静态代理、动态代理。 【2】抽象角色、真是角色、代理角色。代理后一般会做一些附属操作。 package com.day.service; public interface Rent { public void rentHouse(); } ****************** package com.day.pojo; import com.day.service.Rent; // 房东 public class Host implements Rent { @Override public void rentHouse() { System.out.println("房东出租房子"); } } ****************** package com.day.pojo; public class Client { } ****************** package com.day.pojo; import com.day.service.Rent; // 代理 public class Proxy implements Rent { // 拿房东 Host host; public Proxy(Host host) { this.host = host; } @Override public void rentHouse() { seeHouse(); sign(); fee(); host.rentHouse(); } // 看房 public void seeHouse() { System.out.println("中介带你看房"); } // 收中介费 public void fee() { System.out.println("收中介费"); } // 签合同 public void sign() { System.out.println("签合同"); } } ************************** package com.day; import com.day.pojo.Host; import com.day.pojo.Proxy; public class DayApplication { public static void main(String[] args) throws Exception { Host host = new Host(); Proxy proxy = new Proxy(host); proxy.rentHouse(); } } *********************** 【3】代理的好处:可以使真是角色的操作更加纯粹。公共也就代理角色实现,实现了业务分工。公共业务发生扩展时方便集中管理。缺点:真是角色1V1代理类
****************************************************************************************************************************************************************************
11、静态代理再次理解 【1】感觉真的很美妙...。保持原有的类不变。也就是AOP的实现机制。 package com.day.service; public interface UserService { public void insert(); public void delete(); public void update(); public void select(); } ***************************** package com.day.service.imp; import com.day.service.UserService; // 真是对象 public class UserServiceImp implements UserService { @Override public void insert() { System.out.println("增加"); } @Override public void delete() { System.out.println("删除"); } @Override public void update() { System.out.println("修改"); } @Override public void select() { System.out.println("查询"); } } ***************************** package com.day.pojo; import com.day.service.UserService; import com.day.service.imp.UserServiceImp; public class Proxy implements UserService { UserServiceImp userServiceImp; public Proxy(UserServiceImp userServiceImp) { this.userServiceImp = userServiceImp; } @Override public void insert() { log("add"); userServiceImp.insert(); } @Override public void delete() { log("delete"); userServiceImp.delete(); } @Override public void update() { log("update"); userServiceImp.update(); } @Override public void select() { log("select"); userServiceImp.select(); } // 日志方法 public void log(String msg) { System.out.println(msg + "打印日志..."); } } ***************************** package com.day; import com.day.pojo.Proxy; import com.day.service.UserService; import com.day.service.imp.UserServiceImp; // 需求 加日志 public class DayApplication { public static void main(String[] args) throws Exception { /*UserServiceImp userServiceImp = new UserServiceImp(); userServiceImp.insert();*/ UserServiceImp userServiceImp = new UserServiceImp(); Proxy proxy = new Proxy(userServiceImp); proxy.insert(); proxy.select(); } }
****************************************************************************************************************************************************************************
12、动态代理 【1】代理1V1类导致代码很多,怎么处理呢。最核心的点:动态代理的代理类是动态生成的,不是我们直接写好的(利于的是反射技术)。 【2】基于接口的动态代理、基于类的动态代理、 package com.day.service; public interface Rent { public void rent(); } ************************************ package com.day.pojo; import com.day.service.Rent; // 房东 public class Host implements Rent { @Override public void rent() { System.out.println("房东出租房子"); } } ************************************ package com.day.pojo; import com.day.service.Rent; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 用这个类自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { // 被代理的接口 private Rent rent; public ProxyInvocationHandler(Rent rent) { this.rent = rent; } // 生成得到代理对象 public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this); } // 处理代理示例 并反馈结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 本质就是使用反射 sign(); Object object = method.invoke(rent, args); fee(); return object; } public void fee() { System.out.println("收中介费"); } public void sign() { System.out.println("签合同"); } } ************************************ package com.day; import com.day.pojo.Host; import com.day.pojo.ProxyInvocationHandler; import com.day.service.Rent; // 需求 加日志 public class DayApplication { public static void main(String[] args) throws Exception { Host host = new Host(); ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(host); Rent proxy = (Rent) proxyInvocationHandler.getProxy(); // proxy是动态生成的 proxy.rent(); } } ***************************************** 【3】万能代理类。好处:动态代理代理的是一个接口,一般是一类业务,业务之间切换也很方便。 package com.day.pojo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 用这个类自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { // 被代理的接口 private Object target; public ProxyInvocationHandler(Object target) { this.target = target; } // 生成得到代理对象 public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } // 处理代理示例 并反馈结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 本质就是使用反射 log(method.getName()); sign(); Object object = method.invoke(target, args); fee(); return object; } public void fee() { System.out.println("收中介费"); } public void sign() { System.out.println("签合同"); } public void log(String msg) { System.out.println(msg + "打印日志..."); } }
****************************************************************************************************************************************************************************
13、装饰者设计模式 【1】咖啡+调料,当增加咖啡种类、调料种类时,如果一一增加,则类的数量会爆炸。 【2】将每一种咖啡都拥有所有的调料,这样就可以随便匹配。更好的方案是使用装饰者模式。 【3】将新功能动态的附加到对象上。邮寄快递需要包装下。主体是咖啡,装饰者是调料。 【4】实际案例:Drink抽象类,ShortBlack单品咖啡,Decorator是一个装饰类(含有被装饰对象)。cost方法存在递归计算。 【5】这个在实际的商城中也可以用到价格叠加,卧槽。
****************************************************************************************************************************************************************************
14、组合模式 【1】展示学校、学院、系。看成树结构,组合模式。 package com.day.service; import lombok.Data; @Data public abstract class Organization { private String name; private String des; public Organization(String name, String des) { super(); this.name = name; this.des = des; } public abstract void print(); // 打印 public void add(Organization organization) { // 默认实现 throw new UnsupportedOperationException(); } protected void remove(Organization organization) { // 默认实现 throw new UnsupportedOperationException(); } } ******************************** package com.day.service.imp; import com.day.service.Organization; import java.util.ArrayList; import java.util.List; public class University extends Organization { List<Organization> organizationList = new ArrayList<>(); // 构造器 public University(String name, String des) { super(name, des); } @Override public void print() { System.out.println("----------" + getName() + "---------------" + getDes()); for (Organization temp : organizationList) { temp.print(); } } @Override public void add(Organization organization) { organizationList.add(organization); } @Override protected void remove(Organization organization) { organizationList.remove(organization); } @Override public String getName() { return super.getName(); } @Override public String getDes() { return super.getDes(); } } ******************************** package com.day.service.imp; import com.day.service.Organization; import java.util.ArrayList; import java.util.List; public class College extends Organization { List<Organization> organizationList = new ArrayList<>(); // 构造器 public College(String name, String des) { super(name, des); } @Override public void print() { System.out.println("----------" + getName() + "---------------" + getDes()); for (Organization temp : organizationList) { temp.print(); } } @Override public void add(Organization organization) { organizationList.add(organization); } @Override protected void remove(Organization organization) { organizationList.remove(organization); } @Override public String getName() { return super.getName(); } @Override public String getDes() { return super.getDes(); } } ******************************** package com.day.service.imp; import com.day.service.Organization; import java.util.ArrayList; import java.util.List; public class Department extends Organization { List<Organization> organizationList = new ArrayList<>(); // 构造器 public Department(String name, String des) { super(name, des); } @Override public void print() { System.out.println("----------" + getName() + "---------------" + getDes()); /* for (Organization temp : organizationList) { temp.print(); }*/ } @Override public String getName() { return super.getName(); } @Override public String getDes() { return super.getDes(); } } ******************************** package com.day; import com.day.service.Organization; import com.day.service.imp.College; import com.day.service.imp.Department; import com.day.service.imp.University; // 需求 加日志 public class DayApplication { public static void main(String[] args) throws Exception { // 从大到小 Organization university = new University("哈工大", "东三省最牛批"); Organization college = new College("计算机学院", "亚洲前四"); Organization college_2 = new College("软件学院", "也很牛批"); college.add(new Department("计算机专业1", "可以")); college.add(new Department("计算机专业2", "非常可以")); college.add(new Department("计算机专业3", "非常牛批")); college_2.add(new Department("软件专业1", "可以")); college_2.add(new Department("软件专业2", "非常可以")); college_2.add(new Department("软件专业3", "非常牛批")); university.add(college); university.add(college_2); university.print(); } } 【2】源码用到的组合模式:HashMap。接口类的总览很重要,面向接口编程。
****************************************************************************************************************************************************************************
15、外观模式 【1】很多设备需要控制,太多的遥控器,所以你需要一个万能遥控器。 【2】外观模式也叫过程模式,给业务封装一个更高级的接口。感觉就是包装了下。 package com.day.service.imp; public class DvdPlayer { // 单例模式 private static DvdPlayer dvdPlayer = new DvdPlayer(); public static DvdPlayer getInstance() { return dvdPlayer; } public void start() { System.out.println("DVD 打开"); } public void stop() { System.out.println("DVD 关闭"); } public void play() { System.out.println("DVD 播放"); } } ************************************* package com.day.service.imp; public class TvPlayer { // 单例模式 private static TvPlayer tvPlayer = new TvPlayer(); public static TvPlayer getInstance() { return tvPlayer; } public void start() { System.out.println("电视 打开"); } public void stop() { System.out.println("电视 关闭"); } public void play() { System.out.println("电视 播放"); } } ************************************* package com.day.service.imp; public class AirPlayer { // 单例模式 private static AirPlayer airPlayer = new AirPlayer(); public static AirPlayer getInstance() { return airPlayer; } public void start() { System.out.println("空调 打开"); } public void stop() { System.out.println("空调 关闭"); } public void play() { System.out.println("空调 播放"); } } ************************************* package com.day; import com.day.service.imp.AirPlayer; import com.day.service.imp.DvdPlayer; import com.day.service.imp.TvPlayer; // 主函数入口 public class DayApplication { private AirPlayer airPlayer; private DvdPlayer dvdPlayer; private TvPlayer tvPlayer; public DayApplication() { super(); this.airPlayer = AirPlayer.getInstance(); this.tvPlayer = TvPlayer.getInstance(); this.dvdPlayer = DvdPlayer.getInstance(); } public static void main(String[] args) throws Exception { DayApplication dayApplication = new DayApplication(); dayApplication.ready(); dayApplication.play(); } // 准备 public void ready() { airPlayer.start(); dvdPlayer.start(); tvPlayer.start(); } public void play() { airPlayer.play(); dvdPlayer.play(); tvPlayer.play(); } }
****************************************************************************************************************************************************************************
16、享元模式 【1】就是有一份源代码,然后根据不同的需求修改。用共享模式支持大量细粒度的对象。棋子内部状态是颜色,坐标是外部状态。 package com.day.service; import com.day.service.imp.User; public abstract class WebSite { public abstract void use(User user); } **************************** package com.day.service.imp; import com.day.service.WebSite; public class ConcreteWebSite extends WebSite { private String type = "";// 网站发布形式 public ConcreteWebSite(String type) { this.type = type; } @Override public void use(User user) { System.out.println(user.getName() + "网站的发布形式为:" + type); } } **************************** package com.day.service.imp; import com.day.service.WebSite; import java.util.HashMap; // 工厂类 public class WebSiteFactory { // 集合 充当池子的作用 private HashMap<String, ConcreteWebSite> hashMapPool = new HashMap<>(); // 根据网站类型,返回网站。如果没有网站就创建,然后放入到池子中并返回 public WebSite getWebSiteInstance(String type) { if (!hashMapPool.containsKey(type)) { // 没有就创建 hashMapPool.put(type, new ConcreteWebSite(type)); } return (WebSite) hashMapPool.get(type); } // 获取网站分类的总数 public int getWebSiteNum() { return hashMapPool.size(); } } **************************** package com.day; import com.day.service.WebSite; import com.day.service.imp.User; import com.day.service.imp.WebSiteFactory; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { WebSiteFactory webSiteFactory = new WebSiteFactory(); User user = new User(); user.setName("陈翔"); WebSite webSite = webSiteFactory.getWebSiteInstance("新闻"); webSite.use(user); user.setName("蘑菇头"); webSite = webSiteFactory.getWebSiteInstance("博客"); webSite.use(user); webSite = webSiteFactory.getWebSiteInstance("博客"); webSite.use(user); webSite = webSiteFactory.getWebSiteInstance("博客"); webSite.use(user); System.out.println("网站分类一共 " + webSiteFactory.getWebSiteNum()); } }
****************************************************************************************************************************************************************************
17、模板模式 【1】在抽象类中公开定义其他方法的模板。 package com.day.service; // 抽象类 public abstract class SoybeanMilk { // 模板方法 用final修饰,不让子类覆盖 public final void make() { select(); addAnother(); withWater(); beat(); } void select() { System.out.println("1 选择鲜豆"); } public abstract void addAnother(); // 子类实现 void withWater() { System.out.println("3 黄豆与配料开始浸泡 需要3小时"); } void beat() { System.out.println("4 放到豆浆机打磨"); } } ******************************************* package com.day.service.imp; import com.day.service.SoybeanMilk; public class RedBeanMilk extends SoybeanMilk { @Override public void addAnother() { System.out.println("2 加入好的红豆"); } } ******************************************* package com.day.service.imp; import com.day.service.SoybeanMilk; public class BlackBeanMilk extends SoybeanMilk { @Override public void addAnother() { System.out.println("2 加入上号的芝麻"); } } ******************************************* package com.day; import com.day.service.imp.BlackBeanMilk; import com.day.service.imp.RedBeanMilk; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { // 红豆 RedBeanMilk redBeanMilk = new RedBeanMilk(); redBeanMilk.make(); System.out.println("-------------------------------------------------------"); // 芝麻 BlackBeanMilk blackBeanMilk = new BlackBeanMilk(); blackBeanMilk.make(); } }
****************************************************************************************************************************************************************************
18、命令模式 【1】面临的场景很像外观模式。还是万能遥控器。感觉写来写去都差不多了呢...卧槽 package com.day.service; //命令接口 public interface Command { public void exe(); // 执行 public void undo(); // 撤销操作 } *************************************** package com.day.service.imp; import com.day.service.Command; public class LightOnCommand implements Command { LightReceiver lightReceiver; // 构造器接受实例 public LightOnCommand(LightReceiver lightReceiver) { this.lightReceiver = lightReceiver; } @Override public void exe() { lightReceiver.on(); } @Override public void undo() { lightReceiver.off(); } } *********************************** package com.day.service.imp; public class LightReceiver { public void on() { System.out.println("电灯 打开"); } public void off() { System.out.println("电灯 关闭"); } } *********************************** package com.day; import com.day.service.imp.LightOnCommand; import com.day.service.imp.LightReceiver; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { LightReceiver lightReceiver = new LightReceiver(); LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver); lightOnCommand.exe(); lightOnCommand.undo(); } }
****************************************************************************************************************************************************************************
19、访问者模式 【1】在被访问类里,加一个对外提供接待访问者的接口。 【2】这里还是需要深度理解下的。
****************************************************************************************************************************************************************************
20、迭代器模式 【1】组合者模式解决过学校、学院、专业的问题。用一致的方法遍历集合元素。 【2】越来越难,强人所难呀,卧槽...
****************************************************************************************************************************************************************************
21、观察者模式 【1】设计开放型的API package com.day.service.imp; import lombok.Data; // 核心类 最新的天气信息、含有NowCondition、数据有更新就主动调用 @Data public class WeatherData { private float hot; private float press; private float water; private NowCondition nowCondition; public WeatherData(NowCondition nowCondition) { this.nowCondition = nowCondition; } public void dataChange() { nowCondition.update(hot, press, water); } public void setData(float hot, float press, float water) { this.hot = hot; this.press = press; this.water = water; // 推送给接入方 dataChange(); } } ************************************* package com.day.service.imp; public class NowCondition { private float hot; private float press; private float water; // 更新天气 public void update(float hot, float press, float water) { this.hot = hot; this.press = press; this.water = water; display(); } public void display() { System.out.println("今天温度 " + hot); System.out.println("今天气压 " + press); System.out.println("今天湿度 " + water); } } ********************************* package com.day; import com.day.service.imp.NowCondition; import com.day.service.imp.WeatherData; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { NowCondition nowCondition = new NowCondition(); WeatherData weatherData = new WeatherData(nowCondition); // 更新天气情况 weatherData.setData(10.1f, 20.1f, 30.1f); // 天气变化 System.out.println("天气情况发生变化.........................................................."); weatherData.setData(20.1f, 30.1f, 40.1f); } } 【2】观察者模式的改进 package com.day.service; // 接口 WeatherData来实现 public interface Subject { public void regObserver(Observe observe); public void removeObserver(Observe observe); public void notifyObserver(); } ********************************* package com.day.service; // 观察者接口 public interface Observe { public void update(float hot, float press, float water); } ********************************* package com.day.service.imp; import com.day.service.Observe; import com.day.service.Subject; import java.util.ArrayList; import java.util.List; public class WeatherData implements Subject { private float hot; private float press; private float water; private ArrayList<Observe> observeArrayList; public WeatherData() { observeArrayList = new ArrayList<>(); } public void dataChange() { //nowCondition.update(hot, press, water); notifyObserver(); } public void setData(float hot, float press, float water) { this.hot = hot; this.press = press; this.water = water; // 推送给接入方 dataChange(); } @Override public void regObserver(Observe observe) { observeArrayList.add(observe); } @Override public void removeObserver(Observe observe) { if (observeArrayList.contains(observe)) { observeArrayList.remove(observe); } } @Override public void notifyObserver() { for (Observe temp : observeArrayList) { temp.update(hot, press, water); } } } ********************************* package com.day.service.imp; import com.day.service.Observe; public class NowCondition implements Observe { private String coName; private float hot; private float press; private float water; public NowCondition(String coName) { this.coName = coName; } // 更新天气 public void update(float hot, float press, float water) { this.hot = hot; this.press = press; this.water = water; display(); } public void display() { System.out.println(coName + " 今天温度 " + hot); System.out.println(coName + " 今天气压 " + press); System.out.println(coName + " 今天湿度 " + water); } } ********************************* package com.day; import com.day.service.imp.NowCondition; import com.day.service.imp.WeatherData; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { NowCondition nowCondition = new NowCondition("新浪"); NowCondition nowCondition_1 = new NowCondition("百度"); WeatherData weatherData = new WeatherData(); weatherData.regObserver(nowCondition); //注册 weatherData.regObserver(nowCondition_1); //注册 // 测试 weatherData.setData(1f, 2f, 3f); //移出 weatherData.removeObserver(nowCondition_1); weatherData.setData(1f, 2f, 3f); } }
****************************************************************************************************************************************************************************
22、备忘录模式 【1】在不破坏封装性的前提下,捕获一个对象的内部状态,后面可以恢复到保存前的状态。 package com.day.service.imp; import java.util.ArrayList; import java.util.List; public class Care { private List<Memento> mementoList = new ArrayList<>(); public void add(Memento memento) { mementoList.add(memento); } public Memento get(int index) { return mementoList.get(index); } } ********************************** package com.day.service.imp; import lombok.Data; @Data public class Origin { private String state; // 可以保存状态对象的方法 public Memento saveState() { return new Memento(state); } public void getState(Memento memento) { state = memento.getState(); } } ********************************** package com.day.service.imp; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class Memento { private String state; } ********************************** package com.day; import com.day.service.imp.Care; import com.day.service.imp.Origin; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { Origin origin = new Origin(); Care care = new Care(); origin.setState("状态1 :攻击力 100"); care.add(origin.saveState()); // 保存当前状态 origin.setState("状态2:攻击力 84"); care.add(origin.saveState()); // 保存当前状态 origin.setState("状态3:攻击力 92"); care.add(origin.saveState()); // 保存当前状态 // 当前状态 System.out.println("当前状态 " + origin.getState()); // 恢复到状态1 origin.getState(care.get(0)); // 这里是关键 System.out.println("回复到状态1 " + origin.getState()); } }
****************************************************************************************************************************************************************************
23、状态模式 【1】抽奖活动。这个可能会很实用。
****************************************************************************************************************************************************************************
24、策略模式 【1】管理不同种类鸭子的信息。让算法的变化独立于实用算法的客户。也是不同维度聚合、组合的思想。
****************************************************************************************************************************************************************************
25、职责链模式 【1】解决交税类似问题。 【2】传统的switch是很难面对变动问题的。就是A能处理就处理,不能处理交给B,B能处理就处理,不能处理交给C...一个处理链路 package com.day.service; import com.day.service.imp.PurchaseRequest; import lombok.Data; @Data public abstract class Approver { public Approver approver; // 下一个处理者 String name;// 姓名 public Approver(String name) { this.name = name; } // 处理审批请求的方法 public abstract void processRequest(PurchaseRequest purchaseRequest); } ********************************** package com.day.service.imp; import lombok.Data; @Data public class PurchaseRequest { private int type; private float price = 0.0f; private int id = 0; //构造器 public PurchaseRequest(int type, float price, int id) { super(); this.type = type; this.price = price; this.id = id; } } ********************************** package com.day.service.imp; import com.day.service.Approver; public class DepartmentApprover extends Approver { public DepartmentApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if (purchaseRequest.getPrice() <= 5000) { System.out.println("编号" + purchaseRequest.getId() + "被" + this.getName() + "处理"); } else { getApprover().processRequest(purchaseRequest); } } } ********************************** package com.day.service.imp; import com.day.service.Approver; public class CollegeApprover extends Approver { public CollegeApprover(String name) { super(name); } @Override public void processRequest(PurchaseRequest purchaseRequest) { if (purchaseRequest.getPrice() > 5000 && purchaseRequest.getPrice() <= 10000) { System.out.println("编号" + purchaseRequest.getId() + "被" + this.getName() + "处理"); } else { getApprover().processRequest(purchaseRequest); } } } ********************************** package com.day; import com.day.service.imp.CollegeApprover; import com.day.service.imp.DepartmentApprover; import com.day.service.imp.PurchaseRequest; // 主函数入口 public class DayApplication { public static void main(String[] args) throws Exception { PurchaseRequest purchaseRequest = new PurchaseRequest(1, 8000, 1001); DepartmentApprover departmentApprover = new DepartmentApprover("专业长"); departmentApprover.setApprover(new CollegeApprover("院长")); // 这个设置很关键 departmentApprover.processRequest(purchaseRequest); } }