自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(65)
  • 收藏
  • 关注

原创 设计模式详解(十七)——迭代子模式

在上述例子中,我们定义了一个迭代子模式,包括抽象聚合对象、具体聚合对象、抽象迭代子和具体迭代子。Iterator类中定义了迭代器的行为,定义了遍历元素所需的接口,包括first(获取第一个元素)、next(获取下一个元素)和hasNext(判断是否还有更多元素)方法。迭代子模式的核心思想是将遍历集合的行为从集合本身中分离出来,这样集合就可以专注于自己的数据结构,而遍历集合的逻辑可以被封装在迭代子中。迭代子模式是一种行为设计模式,通过将遍历集合对象的行为封装在迭代子对象中,实现了遍历与集合对象的分离。

2024-04-25 22:15:00 846 2

原创 设计模式详解(十六)——观察者模式

在观察者模式中,主题是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。然后我们实现了具体的主题对象类 ConcreteSubject 和具体的观察者对象类 ConcreteObserver,在具体主题对象类中添加、删除和通知观察者对象,更改状态值并且通知所有的观察者对象。因此当后面更多的用户关注该公众号,只要将新的观察者加入到该公众号的用户列表中,当公众号发布新的文章时,就会统一对这些关注该公众号的用户发送通知了,实现广播通信的效果。创建主题(Subject)

2024-04-24 21:30:00 725

原创 设计模式详解(十五)——模板方法模式

模板方法使得子类可以不改变算法的结构即可重新定义该算法的某些特定步骤。该模式通过定义一个抽象类,其中包含一个模板方法,该方法定义了算法的基本结构,并调用一系列抽象方法来完成算法中的特定步骤。比如生活中,假如我们去运动的步骤基本固定的,分为先去运动场,选一种运动类型(比如:篮球,足球,羽毛球等),然后换上对应运动的鞋(比如:篮球鞋,足球鞋,羽毛球鞋等),然后去运动,再回家。模板方法模式是一种行为设计模式,用于定义算法的框架结构,将算法的通用部分抽象到父类中,同时允许子类实现特定步骤,以定制化算法的具体实现。

2024-04-22 21:15:00 1043

原创 设计模式详解(十四)——策略模式

策略模式属于对象行为模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换,且算法的变化不会影响使用算法的客户。比如我们出去玩时可以选择的出行策略有很多种:汽车、火车、飞机,,高铁等每种出行策略都有各自的使用方法,只要能到目的地,我们可以随意更换各种策略。2.增加了对象的数目:由于策略模式将算法单独提取出来封装成策略类,因此会增加系统中类的个数,,从而也具有一定的复杂度。1.客户端必须知道不同策略的存在:客户端必须了解不同策略,以便根据需求选择合适的策略对象,从而具有一定的复杂度。

2024-04-10 20:02:58 831

原创 设计模式详解(十三)——享元模式

享元模式是一种用于优化性能的软件设计模式,它通过共享对象来减少内存中对象的数量,从而降低内存消耗并提高系统性能。享元模式将对象的状态分为内部状态和外部状态,其中一些具有相同内部状态的对象可以被多个对象共享,而不是为每个对象都创建新的实例;而外部状态是变化的,不能共享。虽然我们创建了多次小汽车,但它们相同颜色和相同发动机排量的共享同一个享元对象,因此创建相同相同颜色和相同发动机排量的汽车时,可以减少了内存占用。将一辆小汽车可以看做是一个享元对象,共享的部分是小汽车的基本属性,比如颜色,发动机排量等。

2024-04-07 20:55:10 1039

原创 设计模式详解(十二)——外观模式

如果不使用外观模式,客户端通常需要和子系统内部的多个模块交互,也就是说客户端会和这些模块之间都有依赖关系,任意一个模块的变动都可能会引起客户端的变动。使用外观模式后,客户端只需要和外观类交互,即只和这个外观类有依赖关系,不需要再去关心子系统内部模块的变动情况了。外观模式的核心思想主要是通过创建一个外观类,将复杂系统的内部实现细节隐藏起来,只暴露出一个简化的接口给客户端。在上述例子中,音乐功能、视频功能和联网功能是子系统,Computer是外观类,封装了对这些子系统的调用,并提供了简化的接口给客户端。

2024-03-16 20:45:00 854

原创 设计模式详解(十一)——组合模式

组合模式(Composite Pattern)是一种结构型设计模式,又叫部分整体模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。在使用组合模式时,要多加考虑方式,有的时候可以与迭代器模式配合使用。组合模式,它是一种非常强大的结构型设计模式,用于创建复杂的对象结构,允许用户以统一的方式处理单个对象和复合对象。通过组合模式,你可以构建出具有层次结构的对象模型,这些对象可以像单个对象一样被简单、一致地使用。组合模式是一种非常普遍和常用的模式,接口服务互相组合,提供更丰富的接口,实现复杂的业务逻辑。

2024-02-21 21:30:00 942

原创 设计模式详解(十)——装饰器模式

装饰器模式也称为包装模式是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责,即增加其额外功能,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。从代码层面而言,是对类的一个扩展或者是修饰,从传统方法而言,我们可以使用继承来对某一个类进行扩展,但是往往会导致会出现非常多的子类,如果我们要想避免这种情况,那么我们就可以使用设计模式中的——装饰器模式。比如平时我们都肯定喝过奶茶,奶茶肯定有很多种,而且点的奶茶,还可以加料,比如加珍珠,加椰果之类的。这就可以用装饰器模式处理了。

2023-11-11 21:15:00 632

原创 设计模式详解(九)——桥接模式

与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。(1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

2023-09-16 20:15:00 548

原创 idea使用checkStyle出错——The scan failed due to an exception: An error occurred while scanning a file.

去checkstyle-idea官网下载所需要的版本,如果需要最新的,可以直接在idea中更新就可以,但是想要其它版本,需要去官网下载旧版本。(如果你们不是这两个版本,还是报这个错误,也可能是版本不兼容问题,可以更换CheckStyle-IDEA 版本,或者更新IDEA)IntelliJ IDEA 2021.3.3 (社区版)和CheckStyle-IDEA 版本:5.76.0不兼容,导致运行报错。安装完成后,需要重启idea才可以生效。然后去idea中将原来的CheckStyle-IDEA卸载。

2023-07-25 23:30:00 685

原创 设计模式详解(八)——代理模式

当我们使用代理对象来代替对真实对象的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。当我们想控制一个对象的访问时,可以使用代理模式把客户代码和实际对象隔离开来,提供一个中间层来管理对实际对象的访问,把客户和对象解耦合。通俗点举个例子解释:当我们要访问一些国外的网站时,就发现访问不了,这个时候就会需要用到VPN,他可以帮助我们去访问一些国内不能访问的网站,也就是说他代理了这个访问过程,把结果返回给了我们。代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象;

2023-07-05 01:00:00 342

原创 设计模式详解(七)——适配器模式

类适配器模式是通过让Adapter(适配器)实现Target(被适配者)的抽象接口,然后继承Adaptee(要适配者),具体适配过程是由我们的适配器的Resuest()方法中对Adaptee(要适配者)的SpecificRequest()方法进行适配,使得适配器的Request()方法返回我们需要的被适配者,供我们使用。适配器模式的用意是要改变源的接口,以便于目标接口相容。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适配器两种,在对象适配器模式中,适配器与适配者之间是关联关系;

2023-06-12 20:30:06 3037

原创 设计模式详解(六)——原型模式

或者创建一个新对象,复制对象时仅仅复制对象本身,包括基本属性,但该对象的属性引用其他对象时,该引用对象不会被复制,即拷贝出来的对象与被拷贝出来的对象中的属性引用的对象是同一个(仍指向原有属性所指向的对象的内存地址);就是用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

2023-05-22 20:22:41 626

原创 设计模式详解(五)——建造者模式

它是将一个复杂对象的构建过程与它的实现表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。1.需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。建造者模式,相当于是对工厂生产产品的一种装配,由于这种装配可能随时改变,所以需要抽取出来,实现产品局部与整体的解耦。

2023-05-13 19:45:00 1193 1

原创 设计模式详解(四)——抽象工厂模式

抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展。抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展。抽象工厂模式:便于交换产品系列,同时让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端。

2023-05-13 00:15:00 1123

原创 设计模式详解(三)——工厂方法模式

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。(1)一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;(2)具体工厂(ConcreteCreator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

2023-05-12 00:00:00 351

原创 设计模式详解(二)——单例模式

单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。这种类型的设计模式属于创建型模式,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛,它提供了一种创建对象的最佳方式。3、单例类必须给所有其他对象提供这一实例。2、单例类必须自己创建自己的唯一实例。

2023-05-11 00:30:00 447

原创 设计模式详解(一)

设计模式(英语 design pattern)是对面向对象设计中反复出现的问题的解决方案。这个术语是在1990年代由Erich Gamma等人从建筑设计领域引入到计算机科学中来的。这个术语的含义还存有争议。算法不是设计模式,因为算法致力于解决问题而非设计问题。设计模式通常描述了一组相互紧密作用的类与对象。设计模式提供一种讨论软件设计的公共语言,使得熟练设计者的设计经验可以被初学者和其他设计者掌握。设计模式还为软件重构提供了目标。

2023-03-12 16:15:00 423 1

原创 设计模式之七大原则(三)——接口隔离原则、迪米特法则、组合/聚合复用原则

接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。根绝接口隔离原则,当一个接口太大时,我们需要将它分割成一些细小的接口,使用该接口的客户端只需知道与之相关的方法即可。每一个接口应该承担一种相对独立的角色,不干不该干的事情,干该干的事请。这里的"接口"往往有两种不同的定义:一种是指一个类型所具有的方法特征的集合,仅仅是一种逻辑上的抽象;

2023-03-11 20:15:00 818

原创 设计模式之七大原则(二)——里氏替换原则、依赖倒转原则

上层模块不应该依赖下层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象,其核心思想是:要面向接口编程,不要面向实现编程。

2023-03-03 22:15:00 1205

原创 设计模式之七大原则(一)——单一职责原则、开放-关闭原则

把创建Type1 类做成抽象类,并提供一个抽象的 type方法,让子类去实现即可,这样我们有新的水果种类时,只需要让新的水果类继承 Type1 ,并实现 type方法即可,使用方的代码就不需要修改了, 从而满足了开闭原则。简单说明一下,首先我们可以对某个类来说,即一个类应该只负责一项职责。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。在后来发现新问题,并不是所有的鸟类都会飞翔的,比如企鹅就不会了,修改时如果遵循单一职责原则的话,那么需要添加一个类。

2023-03-03 22:00:00 1283

原创 拾遗增补(七)——线程异常处理的传递

本示例想要打印“静态的异常处理”的信息,则必须在public void uncaughtException( Thread t, Throwable e)方法中加上 super.uncaughtException (t,e);前面介绍了若干个线程异常处理的方式,那么这些处理的方式如果放在一起运行,会出现什么样的运行结果?创建名称为7.7项目。

2023-01-12 20:04:15 413

原创 拾遗增补(六)——线程组内处理异常

需要注意的是,使用自定义java.lang.ThreadGroup线程组,并且重写uncaughtException方法处理组内线程中断行为时,每个线程对象中的run()方法内部不要有异常catch语句,如果有catch语句,则public void uncaughtException(Thread t, Throwable e)不执行。从运行的结果来看,在默认的情况下,线程组中的一个线程出现异常不会影响其他线程的运行。如果要实现线程组内一个线程出现异常后,全部线程都停止运行的话,需要如何实现呢?

2023-01-12 20:04:03 831

原创 拾遗增补(五)——线程中出现异常的处理

程序运行后在控制台输出空指针异常。在 Java 的多线程技术中,可以对多线程中的异常进行“捕捉”,使用的是 UncaughtExceptionHandler 类,从而可以对发送的异常进行有效的处理。在 Java 的多线程技术中,可以对多线程中的异常进行“捕捉”,使用的是 UncaughtExceptionHandler 类,从而可以对发送的异常进行有效的处理。方法 setDefaultUncaughtExceptionHandler() 的作用是为指定线程类的所有线程对象设置默认的异常处理器。

2023-01-03 20:39:48 426 1

原创 拾遗增补(四)——SimpleDateFormat 非线程安全

类 SimpleDateFormat 主要负责日期的转换与格式化,但在多线程的环境中,使用此类容易造成数据转换及处理的不准确,因为 SimpleDateFormat 类并不是线程安全的。

2023-01-03 20:39:36 493

原创 拾遗增补(三)——使线程具有有序性

正常的情况下,线程在运行时多个线程之间执行任务的时机是无序的。可以通过改造代码的方式使它们运行具有有序性。创建名称为7.3的项目。

2022-12-29 19:53:36 242

原创 拾遗增补(二)——线程组

可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示:线程组的作用是:可以批量管理线程或线程组对象,有效地对线程或线程组对象进行组织。

2022-12-29 19:52:37 787

原创 拾遗增补(一)——线程的状态

线程对象在不同的运行时期有不同的状态,状态信息就存在于State枚举类中。调用与线程有关的方法是造成线程状态改变的主要原因,使用Java多线程技术,其中线程状态和方法的关系如下图所示:线程与状态关系示意图在调用与线程有关的方法后,会进入不同的次线程状态,这些状态之间某些是可双向切换的,比如 WAITING 和 RUNNING 状态之间可以循环地进行切换;而有些是单向切换的,比如线程销毁后并不能自动进入 RUNNING 状态。

2022-11-25 18:23:18 105

原创 单例模式与多线程(三)

枚举enum和静态代码块的特性相似,在使用枚举时,构造方法会自动调用,也可以应用其这个特性实现单例设计模式。上一节将枚举类进行曝露,违反了”职责单一原则“。

2022-09-13 20:23:31 87

原创 单例模式与多线程(二)

静态代码块中的代码在使用类的时候就已经执行了,所以可以应用静态代码块的这个特性来实现单例设计模式。静态内置类可以达到线程安全问题,但如果遇到序列化对象时,使用默认的方式运行得到的结果还是多例的。DCL可以解决多线程单例模式的非线程安全问题。当然,使用其他的办法也能达到同样的效果。解决办法就是在反序列化中使用readResolve()方法。

2022-09-13 20:22:18 85

原创 单例模式与多线程(一)

前面两个实验虽然使用“立即加载”和“延迟加载”实现了单例设计模式,但在多线程的环境中,前面“延迟加载”示例中的代码完全就是错误的,根本不能实现保持单例的状态。此方法使同步synchronized语句块,只对实例化对象的关键代码进行同步,从语句的结构上来讲,运行的效率的确得到了提升但如果是遇到多线程的情况下还是无法解决得到同一个实例对象的结果。此实验虽然取得一个对象的实例,但如果是在多线程的环境中,就会出现取出多个实例的情况,与单例模式的初衷是相背离的。DCL也是大多数多线程结合单例模式使用的解决方案。

2022-09-13 20:22:08 63

原创 定时器Timer(三)—— 定时器Timer的使用

使用 scheduleAtFixedRate 方法:如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的“结束”时的时间来计算。这就是 Task 任务不追赶的情况。控制台打印的结果证明,在不延时的情况下,如果执行任务的时间没有被延时,则下一次执行任务的时间是上一次任务的开始时间加上 delay 时间。如果执行任务的时间被延时(执行任务的时间大于 delay 的时间),那么下一次任务的执行时间以上一次任务“结束”时的时间为参考来计算。

2022-09-09 19:08:13 452

原创 定时器Timer(二)—— 定时器Timer的使用

该方法的作用是以执行 schedule(TimerTask task,long delay,long period) 方法当前的时间为参考时间,在此时间基础上延迟执行的毫秒数,再以某一间隔时间无限次数地执行某一任务。该方法的作用是以执行 schedule(TimerTask task,long delay) 方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次 TimerTask 任务。凡是使用方法中带有 period 参数的,都是无限循环执行 TimerTask 中的任务。

2022-09-09 19:07:58 414

原创 定时器Timer(一)—— 定时器Timer的使用

定时 / 计划功能在移动开发领域使用较多,比如 Android 技术。定时计划任务功能在 Java 中主要使用的就是 Timer 对象,他在内部使用多线程的方式进行处理,所以它和线程技术还是有非常大的关联的。在 JDK 库中 Timer 类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。Timer 类的主要作用就是设置计划任务,但封装任务的类却是 TimerTask。执行计划任务的代码要放入 TimerTask 的子类中,因为 TimerTask 是一个抽象类。

2022-09-09 19:07:45 3457 1

原创 Lock的使用(七)——使用ReentrantReadWriteLock类

类ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务,这样做虽然保证了实例变量的线程安全性,单效率却是非常低的.所以在JDK中提供了一种读写锁ReentrantReadWriteLock类,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReentrantReadLock来提升该方法的代码运行速度。读写锁表示也有两个锁,一个是读操作相关的锁,也成为共享锁;另一个是写操作相关的锁,也叫排他锁。...

2022-08-26 20:27:20 181

原创 Lock的使用(六)——使用ReentrantLock类

使用Condition对象可以对线程执行的业务进行排序规划。说明线程在等待时间到达前,可以被其他线程提前唤醒。程序运行后出现异常,这是正常现象。2秒后被其他线程所唤醒。10秒后自动唤醒自己。...

2022-08-26 20:27:06 180

原创 Lock的使用(五)——使用ReentrantLock类

(3)方法void tryLock(long timeout,TimeUnit unit)的作用是:如果给定线程在等待时间内未被另一个线程保持,且当前线程未被中断,则获取该锁定。(1)方法void lockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定(需要等待别的线程释放锁才行),如果已被中断则出现异常。该实验使用的是Lock()方法,说明线程B被interrupt中断了,那么执行lock()则不出现异常,正常执行。在默认的情况下,ReentrantLock类使用的是非公平锁。

2022-08-25 09:09:06 242

原创 Lock的使用(四)——使用ReentrantLock类

比如说有5个线程,每个线程都执行了同一个condition对象的await()方法,则调用getWaitQueueLength(Condition condition)方法的返回值是5。比如有5个线程,1个线程首先执行await()方法,那么在调用getQueueLength()方法后返回值是4,说明有4个线程同时在等待lock的释放。(1)方法int getHoldCount()的作用是查询当前线程保持锁定的个数,也就是调用lock()方法的次数。创建项目4.1.10。创建项目4.1.11。

2022-08-25 09:08:37 125

原创 Lock的使用(三)——使用ReentrantLock类

原因是程序中使用了一个Condition对象,再结合signalAll()方法来唤醒所有的线程,那么唤醒的线程就有可能是同类,所以就出现连续打印“有可能★★连续”或“有可能☆☆连续”的情况了。公平与非公平锁:锁Lock分为"公平锁"和"非公平锁",公平锁标识线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先进先出顺序,而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了。

2022-08-22 19:24:55 119

原创 Lock的使用(二)——使用ReentrantLock类

可以先对线程进行分组,然后再唤醒指定组中的线程。Object类中的 wait(long timeout)方法相当于Condition类中的await(long time,TimeUnit unit)方法。Object类中的notifyAll()方法相当于Condition类中的signalAll()方法。Object类中的notify()方法相当于Condition类中的signal()方法。Object类中的wait()方法相当于Condition类中的await()方法。成功实现等待/通知模式。

2022-08-22 19:24:38 213

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除