2021-05-21

本文详细介绍了设计模式中的单例模式、策略模式和工厂模式。单例模式关注对象的唯一性,包括饿汉式、懒汉式、静态内部类和枚举实现。策略模式用于封装不同的执行策略,如排序中的Comparator接口。工厂模式则分为工厂方法和抽象工厂,用于创建对象,提供扩展性。最后,门面模式和调停者模式用于解耦系统组件,简化交互。
摘要由CSDN通过智能技术生成

浅谈设计模式(一)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

 

前言

       之前读过几本设计模式的书籍比如设计模式之禅,大概都是介绍设计模式模型。最开始读的时候感觉设计模式这块的知识好抽象,23种设计模式一点点去啃去记感觉好难

最近重新学习了设计模式有了新的理解


提示:以下是本篇文章正文内容,下面案例可供参考

一、单例模式Singleton

       说到单例模式大家都很了解了什么懒汉式单例模式饿汉式单例模式。这些个名词之前是困扰我的一大原因之一,因为过于注意这些名词导致我忽略了对代码的理解。

今天再说起单例模式的时候让我们忘记这些名词来感受一下代码本身,会有更深入的理解。

       对于单例模式的应用场景是必须要提到的,常用的场景就是各种工厂类对象,Manager对象或者连接池因为这些个对象在类加载的时候只需要实例化一次即可,这也

是单例模式设计的初衷,接下来就让我们看看单例模式的各种写法和优缺点

      1.俗称的饿汉式单例(最常用的单例模式写法虽然不完美但是问题无伤大雅)

直接贴代码

也可以通过静态块的方式实例化对象

private  static Msg01 INSTANCE;  //静态的实例域
static {
    INSTANCE=new Msg01();
}

       这种模式是我们常用的单例模式写法,其中的缺点就是有些人认为这样写会造成虚拟机在类加载的时候就会实例化对象,这样不管用不用都会产生对象(个人认为这种是可以接受的)

为了解决这个问题就产生了懒汉式单例模式

       2.懒汉式单例模式

由通过判断INSTANCE对象来决定是否实例化,这样就在多线程访问的时候会导致生成多个对象,虽然解决了实例化对象的问题但是引起了更糟糕的状况,线程不安全

了。所以我们要在方法上加锁  public static synchronized Msg05 getInstance(){} 这样又会导致效率大大降低,所以我们又要引入双重判断加入同步代码块来解决效率问题

//此处判断是造成多线程非单例问题的地方
if(INSTANCE==null){
    synchronized(Msg02.class){
        if(INSTANCE==null){
            try {
                Thread.sleep(2);
            }catch (Exception e){

            }
            INSTANCE=new Msg05();
        }
    }
}

对于第一种饿汉式单例模式解决方案还有一种方法就是引入静态内部类的方式,是可以避免对象实例化的问题 以为外部类在加载的时候是不会实例化静态内部类的而且内部类

也会隐藏起来不被外部访问到以确保对象的唯一

        3.静态内部类饿汉式

完美解决实例化对象问题还不会造成现成不安全

当然还有一种解决方式

       4.枚举单例

枚举单例的优势在于枚举类是没有构造器的所以可以有效避免被反序列化

二、策略模式Strategy


        策略模式封装的是做一件事情不同的执行方式,最典型的应用是我们在进行排序的时候用到的比较器Comparator接口,例如我们要对一个数组进行排序。

如果不使用策略模式,当定义一个排序方法public void sort(int[] a) 对整型进行排序、public void sort(float[] a) 对浮点型进行排序等等我们需要对sort方法进行

重载甚至修改,本着对修改关闭对扩展开放的开闭原则我们要对程序进行改造所以就要应用到策略模式如果我们现在需要一个通过猫的重量对猫进行排序该

怎么办呢应用到策略模式首先要定义比较器接口Comrarable<T> 并定义一个规则方法 int compare(T o1,T o2),然后定义一个猫的实体,有重量属性weight

然后定义一个CatComparator 接口定义比较方式,

然后建立一个Sorter类 定义排序的方法

 

最后在客户端传入比较器进行排序

Cat[] cat={new Cat(9),new Cat(4),new Cat(5)};
Sorter sort=new Sorter<Cat>();
sort.sort(cat,new CatComparator());
System.out.println(Arrays.toString(cat));

这样可以很好的扩展不通的排序方法这就是策略模式,最后是策略模式的类图

 


三、工厂系列Factory

       凡是能产生对象,方法都可以称之为工厂。工厂设计模式分为工厂方法和抽象工厂,简单来说工厂方法模式可以在产品维度进行很好的扩展。而抽象工厂可以在产品一族维度进行

很好的扩展。

      比如,我们现在要定制交通工具,飞机,火车,汽车等等,最简单的我们可以考虑使用简单工厂模式进行扩展定义一个交通工具的工厂VehicleFactory,分别有creatCar,creatPlane,creatTrain三个方法。方法返回值为new 出来的对象。这样就可以实现一个简单工厂的模式,但是这样扩展性实在是太差了。如果有了新的交通工具还需要添加方法。接下来我们重新定义一个Vehicle类定义一个方法 go(交通工具都可以移动),然后定义一个VehicleFactory里面有一个creatVehicle,返回值为Vehicle。接下来具体的交通工具都继承至Vehicle这样就可以对产品进行扩展这个就是我们说的工厂方法模式。

     现在我们的需求又增加了,我们在开车的时候需要吃东西(虽然现实不允许哈哈我们暂且拿他举例子),还需要使用武器进行射击。那么车,食品,武器就是一个产品族。如果在魔法世界我们可以骑扫帚吃蘑菇使用魔法棒攻击,这个时候就需要我们对产品族进行很好的扩展。我们来想一下怎么实现。首先定义三个抽象类(具体是定义抽象类还是接口我们一般总结为形容词用接口定义名词用抽象类定义),食品,武器,和交通工具。Food,Weapon,Vehicle。三个类中定义一个抽象方法print方法进行输出。然后定义一个抽象工厂类VehicleFactory,定一个抽象方法creat,然后在creat方法里面创建出对应的Food,Weapon,Vehicle对象并调用他们的print方法。这样我们在客户端调用的时候就可以用工厂子类去扩展VehicleFactory,是现实工厂还是魔法工厂或者火星工厂,然后在具体的工厂里实现用的是什么交通工具,吃的是什么食物用的武器等等。这样就是抽象工厂模式可以对产品族进行很好的扩展。

四、Facade门面-Mediator调停者

     接下来介绍两个比较类似的模式门面和调停者,这两个模式解决的问题是解耦。举个例子我们在去政府部门办事儿的时候有时候办一件事需要去好多地方办理,这时候我们多么希望有一个门面跟我们对接替我们协调内部的所有事情,这个封装内部逻辑的类就叫做门面模式,有了他的存在我们再也不用关心内部的负责的逻辑只需要访问提供的接口即可,如果有了新的逻辑加入只需要改动内部即可不需要把新增的同其他所有的在进行联系

      与其相似的是调停者模式,他是解耦内部复杂逻辑的,在门面进行协调的时候他们的内部还是存在好多部门,部门之间的联系也是很紧密的,如果增加一个新的部门还要跟其他所以部门进行联系,这时候我们需要一个调停者对部门之间进行协调。最好的例子就是消息中间件的应用,所有部门有消息扔进消息中间件,其他部门想用再去中间件里面去取即可,有效解耦

以上就是我们比较常用的模式,其他的还有一些后面会陆续提到。

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

 

 

2021-03-26 20:54:33,596 - Model - INFO - Epoch 1 (1/200): 2021-03-26 20:57:40,380 - Model - INFO - Train Instance Accuracy: 0.571037 2021-03-26 20:58:16,623 - Model - INFO - Test Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Best Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Save model... 2021-03-26 20:58:16,623 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 20:58:16,698 - Model - INFO - Epoch 2 (2/200): 2021-03-26 21:01:26,685 - Model - INFO - Train Instance Accuracy: 0.727947 2021-03-26 21:02:03,642 - Model - INFO - Test Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Best Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Save model... 2021-03-26 21:02:03,643 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 21:02:03,746 - Model - INFO - Epoch 3 (3/200): 2021-03-26 21:05:15,349 - Model - INFO - Train Instance Accuracy: 0.781606 2021-03-26 21:05:51,538 - Model - INFO - Test Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,538 - Model - INFO - Best Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,539 - Model - INFO - Save model... 2021-03-26 21:05:51,539 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 我有类似于这样的一段txt文件,请你帮我写一段代码来可视化这些训练结果
02-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值