javajavase

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式

创建型模式,共五种

  • 工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式

结构型模式,共七种

  • 适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式

行为型模式,共十一种

  • 策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

其实还有两类:并发型模式和线程池模式

单例设计模式

某个类在整个系统中,只有唯一的一个对象
形式

  • 饿汉式

    1. class Single{
    2. // 内部创建类的对象
    3. // 要求此对象也必须声明为静态的
    4. private static Single instance = new Single();
    5. // 私有化类的构造器
    6. private Single(){
    7. }
    8. // 提供公共的静态的方法,返回类的对象
    9. public static Single getInstance(){
    10. return instance;
    11. }
    12. }
    • 坏处:对象加载时间过长
    • 好处:饿汉式是线程安全的
  • 懒汉式

    1. class Single{
    2. // 声明当前类对象,没有初始化
    3. // 此对象也必须声明为static的
    4. private static Single instance = null;
    5. // 私有化类的构造器
    6. private Single(){
    7. }
    8. // 声明public、static的返回当前类对象的方法
    9. public static Single getInstance(){
    10. if(instance == null){
    11. instance = new Single();
    12. }
    13. return instance;
    14. }
    15. }
    • 好处:延迟对象的创建
    • 目前的写法坏处:线程不安全

      1. //线程安全
      2. class Singleton {
      3. private static Singleton instance;
      4. private Singleton() {
      5. }
      6. public static Singleton getInstance() {
      7. if (instance == null) {
      8. synchronized (Singleton.class) {
      9. if (instance == null) {
      10. instance = new Singleton();
      11. }
      12. }
      13. }
      14. return instance;
      15. }
      16. }

      应用场景

  • 枚举

  • 网站的计数器
  • 应用程序的日志应用
  • 数据库连接池
  • 读取配置文件的类
  • JDK Runtime类
  • Application 也是单例的典型应用
  • Windows的Task Manager (任务管理器)
  • Windows的Recycle Bin (回收站)

模板设计模式

特征

  • 当功能内部一部分实现是确定的,一部分实现是不确定的。可以把不确定的部分暴露出去,让子类去实现
  • 在父类中能确定某个功能的整体的算法结构,但是对于其中的某个步骤,在父类中无法确定,要延迟到子类中去实现,这个时候就可以通过模板设计模式

属于抽象类的应用

  1. abstract class BankTemplateMethod {
  2. // 具体方法
  3. public void takeNumber() {
  4. System.out.println("取号排队");
  5. }
  6. // 办理具体的业务 //钩子方法
  7. public abstract void transact();
  8. public void evaluate() {
  9. System.out.println("反馈评分");
  10. }
  11. // 模板方法,把基本操作组合到一起,子类一般不能重写
  12. public final void process() {
  13. this.takeNumber();
  14. this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
  15. this.evaluate();
  16. }
  17. }
  18. class DrawMoney extends BankTemplateMethod {
  19. public void transact() {
  20. System.out.println("我要取款!!!");
  21. }
  22. }
  23. class ManageMoney extends BankTemplateMethod {
  24. public void transact() {
  25. System.out.println("我要理财!我这里有2000万美元!!");
  26. }
  27. }
  28. public class TemplateMethodTest {
  29. public static void main(String[] args) {
  30. BankTemplateMethod btm = new DrawMoney();
  31. btm.process();
  32. BankTemplateMethod btm2 = new ManageMoney();
  33. btm2.process();
  34. }
  35. }

常见

  • 数据库访问的封装
  • Junit单元测试
  • JavaWeb的Servlet中关于doGet/doPost方法调用
  • Hibernate中模板程序
  • Spring中JDBCTemlate、HibernateTemplate等

代理模式

为其他对象提供一种代理以控制对这个对象的访问
实现AOP的基础

静态代理

三个角色

  • 主题(接口):代理类与被代理类必须都实现主题接口
  • 被代理类
  • 代理类:必须持有被代理类对象的引用 ```java interface Star { void confer();// 面谈 void signContract();// 签合同 void bookTicket();// 订票 void sing();// 唱歌 void collectMoney();// 收钱 }

//被代理类 class RealStar implements Star { public void confer() { } public void signContract() { } public void bookTicket() { } public void sing() { System.out.println(“明星:歌唱~~~”); } public void collectMoney() { } }

//代理类 class Proxy implements Star { private Star real;

  1. public Proxy(Star real) {
  2. this.real = real;
  3. }
  4. public void confer() {
  5. System.out.println("经纪人面谈");
  6. }
  7. public void signContract() {
  8. System.out.println("经纪人签合同");
  9. }
  10. public void bookTicket() {
  11. System.out.println("经纪人订票");
  12. }
  13. public void sing() {
  14. real.sing();
  15. }
  16. public void collectMoney() {
  17. System.out.println("经纪人收钱");
  18. }

}

public class StaticProxyTest { public static void main(String[] args) { Proxy s = new Proxy(new RealStar());

  1. s.confer();
  2. s.signContract();
  3. s.bookTicket();
  4. s.sing();
  5. s.collectMoney();
  6. }

}

  1. <a name="Kctji"></a>
  2. ### [动态代理](https://www.yuque.com/u1135564/javase/ghb2oa#AXOvD)(反射详细讲解)
  3. 三个角色
  4. - 主题(接口):代理类与被代理类必须都实现主题接口
  5. - 被代理类
  6. - 代理类:代理类的创建方式变了,由类加载器对象,在运行时产生
  7. 要点
  8. - 主题:和静态代理模式一样,就是一个接口
  9. - 被代理类
  10. - 和静态代理模式一样,实现了主题的一个实现类
  11. - 负责核心业务逻辑代码
  12. - 处理器
  13. - 用来描述,代理类要做的工作
  14. - 持有被代理类的对象的引用
  15. - 必须实现一个InvocationHandler接口
  16. - 重写一个public Object invoke(Object proxy,Method method,Object[] args)
  17. - 动态的创建代理类或代理类的对象
  18. - Proxy.newProxyInstance(被代理类的类加载器,被代理类实现的所有接口,处理器对象);
  19. - 被代理类的类加载器,用来动态的在内存中生成代理类的Class对象用,即动态生成代理类
  20. - 生成代理类时,要和被代理类实现同样的接口
  21. 应用
  22. - 安全代理:屏蔽对真实角色的直接访问
  23. - 远程代理:通过代理类处理远程方法调用(RMI)
  24. - 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
  25. ---
  26. <a name="ECZLP"></a>
  27. ## 工厂设计模式
  28. [拓展:工厂设计模式.pdf](https://www.yuque.com/attachments/yuque/0/2021/pdf/1379492/1618995091089-682c1dce-2f3c-43d4-a0d3-37d7f1b8d0e5.pdf)
  29. - 目的:使得使用者与创建者分离——把创建某些接口的实现类对象交给工厂来做
  30. <a name="R6OYU"></a>
  31. ### 简单工厂
  32. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1379492/1625558213462-cbd07db9-000e-4bda-9b4f-284b9a3e8432.png#clientId=uf039f5d4-2356-4&from=paste&id=u868a0ec3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=816&originWidth=2258&originalType=url&ratio=1&size=546169&status=done&style=shadow&taskId=ucd5a1e33-48c6-4fec-b49f-12c1d228278)
  33. ```java
  34. //1、所有的要创建的对象,都是符合某个标准的
  35. interface Car {
  36. void run();
  37. }
  38. class BMW implements Car {
  39. public void run(){
  40. ...
  41. }
  42. }
  43. class Benz implements Car {
  44. public void run(){
  45. ...
  46. }
  47. }
  48. //2、设计一个工厂类,用来创建各种各样的Car的实现类的对象
  49. class CarFactory {
  50. public static Car getCar(String name) {
  51. if("宝马".equals(name)) {
  52. return new BMW();
  53. }else if("奔驰".equals(name)) {
  54. return new Benz();
  55. }
  56. return null;
  57. }
  58. }
  • 优点:代码简洁
  • 缺点:当增加新产品时,需要修改工厂方法,违反了“对修改关闭,对扩展开放”的原则

    工厂方法模式

    image.png ```java //1、所有的要创建的对象,都是符合某个标准的 interface Car{ void run(); }

class BMW implements Car{ public void run(){ ….
} }

class Benz implements Car{ public void run(){ ….
} }

//2、每一种产品都自己的工厂生产 //所有的工厂就有共同的特征 interface Factory{ Car getCar(); }

class BMWFactory implements Factory{ public BMW getCar(){ return new BMW(); } }

class BenzFactory implements Factory{ public Benz getCar(){ return new Benz(); } } ```

  • 优点:如果增加新产品,只需要增加对应的工厂即可,不需要修改原来的代码
  • 缺点:类太多,代码复杂

    抽象工厂模式

    image.png
    image.png