首页 > 其他分享 >设计模式

设计模式

时间:2022-11-22 11:25:10浏览次数:45  
标签:class 代理 模式 public new 设计模式 LazyMan

设计模式

共有23中设计模式,Gof23。

  • GoF23

    • 一种思维,一种态度,一种进步

       

  • 创建型模式:(描述怎么创建一个对象)

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

  • 结构型模式:(描述类或对象按照某种布局组成一些更大的结果)

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

  • 行为型模式:(描述类或者对象之间怎么相互协作去共同完成单个对象无法完成的工作)

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

OOP七大原则(面向对象)

  • 开闭原则:对扩展开放,对修改关闭

    • 对一个类添加方法的时候,要避免修改这个类中之前的方法

  • 里氏替换原则:继承必须确保超类所拥有的的也行在子类中仍然成立

    • 不要修改父类中的方法,可以在子类中添加方法

    • 正方形不是长方形

  • 依赖倒置原则:要面向接口编程,不要面向实现编程

    • 面向接口编程

    • 抽象不依赖细节,细节依赖抽象

    • 降低程序之间的耦合性

  • 单一职责原则:控制类的粒度大小、将对象解耦、提高其内聚性

    • 一个方法尽可能干好一件事情

    • 原子性

  • 接口隔离原则:要为各个类建立他们需要的专用接口

    • 降低耦合

  • 迪米特法则:只与你的直接朋友交谈,不跟”陌生人“说话

  • 合成复用原则:尽量先使用组合或者聚合等关联关系来实现,期次才考虑使用继承关系来实现

创建型模式

 

单例模式

不要new对象

只要是单利模式一定构造器私有

  • 恶汉式单例

    初始化的时候就把类中所有的资源都加载到内存中,比较浪费资源

    package com.wx.single;

    /**
    * @BelongsProject: wxStuSCB
    * @BelongsPackage: com.wx.single
    * @Author: wangxiang
    * @CreateTime: 2022-10-18 12:04
    * @Description: 恶汉式单列
    * @Version: 1.0
    * 浪费内存
    */
    public class Hungry {

      //可能会浪费空间
      private byte[] bytes1 = new byte[1024*1024];
      private byte[] bytes2 = new byte[1024*1024];
      private byte[] bytes3 = new byte[1024*1024];
      private byte[] bytes4 = new byte[1024*1024];


      private Hungry(){

      }

      private final static Hungry HUNGRY = new Hungry();

      public static Hungry getInstance(){
          return HUNGRY;
      }
    }

     

  • DCL懒汉式单例

    • 使用的时候进行创建

    • 双重检测锁的模式

      package com.wx.single;

      import java.lang.reflect.Constructor;
      import java.lang.reflect.InvocationTargetException;

      /**
      * @BelongsProject: wxStuSCB
      * @BelongsPackage: com.wx.single
      * @Author: wangxiang
      * @CreateTime: 2022-10-18 12:09
      * @Description: 懒汉式单列模式
      * @Version: 1.0
      */
      public class LazyMan {

         private static boolean wx = false;

         private LazyMan(){
             synchronized (LazyMan.class){
                 if (!wx){
                     wx = true;
                }else {
                     throw new RuntimeException("不用试图使用反射破坏");
                }
            }

        }

         private volatile static LazyMan lazyMan;

         //普通模式
         public static LazyMan getInstance1(){
             if (lazyMan==null){
                 lazyMan = new LazyMan();
            }
             return lazyMan;
        }

         //双重检测锁的模式 懒汉式单列 DCL懒汉式
         public static LazyMan getInstance(){
             if (lazyMan==null){
                 synchronized (LazyMan.class){
                     if (lazyMan==null){
                         lazyMan = new LazyMan();//不是一个原子性操作
                         /**
                             1、分配内存空间
                             2、执行构造方法,初始化对象
                             3、把这个对象指向这个空间

                             理想情况下会按照1、2、3这个顺序执行
                             但是多线程下可能会有问题
                             A线程:按照1、3、2这个执行顺序执行了,指令重排
                             B线程:A线程在执行到第3步的时候lazyMan这个对象在内存空间中是有值的所以不是null,
                                   但是这个时候A线程还没有执行第2步初始化操作,所以会有问题
                             解决方法:添加volatile关键字修饰
                          */


                    }
                }
            }
             return lazyMan;
        }

         //单线程下没问题
         //多线程下会有问题
         public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
      //       for (int i = 0; i <10 ; i++) {
      //           new Thread(()->{
      //               getInstance();
      //           }).start();
      //       }


             LazyMan instance = LazyMan.getInstance();
             Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
             //忽略私有构造器
             declaredConstructor.setAccessible(true);
             LazyMan instance2 = declaredConstructor.newInstance();

             System.out.println(instance);
             System.out.println(instance2);
        }
      }
  • 静态内部类

    package com.wx.single;

    /**
    * @BelongsProject: wxStuSCB
    * @BelongsPackage: com.wx.single
    * @Author: wangxiang
    * @CreateTime: 2022-10-18 12:30
    * @Description: 静态内部类
    * @Version: 1.0
    */
    public class Holder {

       private Holder(){

      }

       public static Holder getInstance(){
           return InnerClass.HOLDER;
      }

       public static class InnerClass{
           private final static Holder HOLDER = new Holder();
      }
    }
  • 单例不安全,因为可以通过反射创建对象

  • 枚举

    枚举中没有无参构造,只有有参构造。通过jad反编译查看,不用使用idea和javap反编译查看,会有问题

    package com.wx.single;

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;

    /**
    * @BelongsProject: wxStuSCB
    * @BelongsPackage: com.wx.single
    * @Author: wangxiang
    * @CreateTime: 2022-10-18 12:42
    * @Description: 枚举本身也是一个class类
    * @Version: 1.0
    */
    public enum EnumSingle {

       INSTANCE;

       public EnumSingle getInstance(){
           return INSTANCE;
      }
    }

    class Test{
       public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
           EnumSingle instance = EnumSingle.INSTANCE;
           Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(null);
           declaredConstructor.setAccessible(true);
           EnumSingle instance1 = declaredConstructor.newInstance();

           System.out.println(instance);
           System.out.println(instance1);

      }
    }

     

工厂模式

  • 作用:

    • 实现了创建者和调用者的分离

    • 详细分类:

      • 简单工厂模式

      • 工厂方法模式

      • 抽象工厂模式

  • OOP七大原则

    • 开闭原则:对扩展开放,对修改关闭

    • 依赖倒置原则:要面向接口编程,不要面向实现编程

    • 迪米特法则:只与你的直接朋友交谈,不跟”陌生人“说话

  • 核心本质:

    • 实例化对象不适用new,用工厂方法代替

    • 将选择实现类,创建对象统一管理和控制。从而将调用者和我们的实现类解耦

  • 三种模式:

    • 简单工厂模式

      • 用来生产同一等级结构中的任意产品(对于增加新的产品,需要扩展已有的代码)

    • 工厂方法模式

      • 用来生产同一等级结构中的固定产品(支持增加任意产品)

    • 抽象工厂模式

      • 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

    根据设计原则:工厂方法模式

    根据实际业务:简单工厂模式

image-20221018140344396

抽象工厂模式

  • 定义:抽象工厂模式提供了一个创建一系列相关或者相互依赖的接口,无需指定他们的具体类

  • 适用场景:

    • 客户端(应用层)不依赖于产品类实例如何被创建、实现等

    • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码

    • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

  • 优点:

    • 具体产品在应用层的代码隔离,无需关心创建的细节

    • 将一个系列的产品统一到一起创建

  • 缺点:

    • 规定勒索有可能被创建的产品集合,产品簇中扩展新的产品困难

    • 正价了系统的抽象性和理解难度

image-20221018141405528

通过idea查看类图:

选中包或类文件,右键,选中 Diagrams,然后选择 Show Diagram

选中 f 和 m 加粗样式这两个按钮,这样就展示了每个类的属性和方法,一目了然,点击 show dependencies

image-20221018145433271

 

建造者模式

  • 建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。

  • 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同 的表示

  • 主要作用:在用户不知道对象的的建造过程和细节的情况下就可以直接创建复杂的对象

  • 用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)

  • 例子:

    • 工厂(建造者模式):负责制造汽车(组装过程和细节在工厂内)

    • 汽车购买者(用户):你需要说出你需要的型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车是怎么组装的(车轮,车门,发动机,方向盘等))

image-20221018150834902

image-20221018153240729

image-20221018153343071

原型模式

  • 克隆

  • Prototype

  • Cloneable接口

  • clone()方法

 

结构型模式

作用:

从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。

适配器模式

  • USB网线转换器

image-20221018162138823

image-20221018162334272

image-20221018162548257

 

代理模式

image-20221019090008929

 

  • 静态代理(每次代理一个角色都要把所有的方法重写,但是实现了业务分工)

    角色分析:

    • 抽象角色:一般会使用接口或者抽象类来解决

    • 真是角色:被代理的角色

    • 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作

    • 客户:访问代理对象的人

    代码步骤:

    1. 接口

      public interface Rent {
         //出租房屋的方法
         public void rent();
      }

       

    2. 真实角色

      public class Host implements Rent{

         @Override
         public void rent() {
             System.out.println("房东要出租房子");
        }
      }

       

    3. 代理角色

      public class Proxy implements Rent {
         private Host host;

         public Proxy(Host host) {
             this.host = host;
        }

         @Override
         public void rent() {
             seyHouse();
             System.out.print("中介帮你租房子");
             host.rent();
             receiveMoney(1235L);

        }

         public void seyHouse(){
             System.out.println("中介带你看房");
        }

         public void receiveMoney(double money){
             System.out.println("收取中介费:"+money);
        }
      }

       

    4. 客户端访问代理

      public class Client {

         public static void main(String[] args) {
             //直接租房
      //       Host host = new Host();
      //       host.rent();
             //通过代理租房
             Proxy proxy = new Proxy(new Host());
             proxy.rent();
        }
      }

       

    代理模式的好处:

    • 可以使真是角色的操作更加纯粹,不用去关心业务

    • 公共业务交给代理角色,实现了业务的分工

    • 公共也放生扩展的时候,方便集中管理

    缺点:

    • 一个真实角色就会产生一个代理角色,代码量会翻倍;开发效率会降低

    image-20221019093213338

     

  • 动态代理

    • 动态代理和静态代理角色一样

    • 动态代理的代理类是动态生成的,不是直接写好的

    • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理

      • 基于接口的---JDK动态代理

      • 基于类:cglib

      • java字节码实现:javasist

    需要了解两个类:Proxy(代理),InvocationHandler(调用处理程序)

    动态代理的好处:

    • 可以使真是角色的操作更加纯粹,不用去关心业务

    • 公共业务交给代理角色,实现了业务的分工

    • 公共也放生扩展的时候,方便集中管理

    • 一个动态代理类代理的是一个接口,一般就是对应的一类业务

    • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

     

桥接模式

image-20221019082156902

image-20221019082449171

image-20221019083623598

image-20221019084955231

 

装饰模式

组合模式

外观模式

享元模式

 

 

 

标签:class,代理,模式,public,new,设计模式,LazyMan
From: https://www.cnblogs.com/wx-36/p/16914547.html

相关文章

  • js设计模式=封装
    js封装案例【1】<script>varBook=function(num){varnum;//类私有变量varname;//类私有变量functioncheck(){};//类私有方法this.checkName=functio......
  • Java设计模式 - 24种
    设计模式的七大原则   开闭原则:对扩展开放、对修改关闭。   单一指责原则:一个类只做一件事。   依赖倒转原则:类似于ioc,采用接口编程。   迪米特原则:高内聚......
  • Java设计模式--单例模式
    单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。单例模式有一下特点:1、单例类只能有一个实例。2、单例类必须自己自己创建自己的唯一实例。3、单例类必须给所有其......
  • 设计模式的基本原则
    设计模式设计模式的世界丰富多彩,比如生产一个个「产品」的工厂模式,衔接两个不相关接口的适配器模式,用不同的方式做同一件事的策略模式,构建步骤稳定、根据构建过程的不同配置......
  • Laravel中用到的设计模式
    1:工厂模式 Auth::user()此处Auth这个类就是工厂中的方法,Auth是注册树中的别名。好处:类似于函数的封装,使对象有一个统一的生成(实例化)入口。当我们对象所对应的类的类名发......
  • 设计模式--创建型模式
    设计模式--创建型模式创建型模式,共五种:工厂方法模式(一个工厂类ReturnNew子类)、抽象工厂模式(一个厂一个子类)、单例模式(恶汉,懒汉)、建造者模式(组合)、原型模式(Cloneable浅......
  • 设计模式--结构型模式
    设计模式--结构型模式结构型模式,共七种:适配器模式(新接口用老实现类)、装饰器模式(同代理,增强)、代理模式(方法前后)、外观模式(计算机包括…)、桥接模式(中间表)、组合模式(树)、......
  • 设计模式--行为型模式
    设计模式--行为型模式行为型模式,共十一种:策略模式(Calculator子类)、模板方法模式(大象装冰箱)、观察者模式(观察者列表)、迭代子模式、责任链模式、命令模式(一层接一层)、备忘......
  • 114:设计模式_工厂模式实现
       设计模式是面向对象语言特有的内容,是我们在面临某一类问题时候固定的做法,设计模式有很多种,比较流行的是:GOF(GoupOfFour)23种设计模式。当然,我们没有必要全部学习......
  • 【设计模式】原型模式:猴头,我叫你一声你敢答应吗?
    1原型模式1.1概述原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象再创建另外一个可定制的对象,无须知......