Java设计模式详解:创建型、结构型、行为型模式分类及六大设计原则解析

Java设计模式一般分为三类:

Java设计模式详解:创建型、结构型、行为型模式分类及六大设计原则解析

创建模式(5种):工厂方法模式、抽象工厂模式、单例模式、构建器模式、

原型模式。

结构模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式

模式、组合模式、享元模式。

行为模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、

责任链模型、命令模型、备忘录模型、状态模型、访客模型、中介模型、解决方案

口译员模式。

设计模式遵循 6 个原则:

1. 开闭原理

对扩展开放,对修改关闭。

2.里氏替换原理

只有当派生类能够替代基类并且不影响软件单元的功能时,基类才能真正被实现。

被重用,派生类还可以在基类的基础上添加新的行为。

3. 依赖倒置原理

这是开闭原则的基础。接口编程依赖于抽象而不是具体。

4. 接口隔离原则

使用多个隔离的接口来减少耦合。

5.德米特原理(最不为人知的原理)

一个实体应该尽可能少地与其他实体交互,以便系统功能模块之间尽可能少地交互。

到独立。

6. 复合复用原则

原则是尽可能使用组合/聚合,而不是继承。继承实际上破坏了类

由于封装,超类方法可以被子类修改。

1、单例模式:保证某个类只有一个实例,自己实例化,并将其提供给整个系统。

实例。

(一)懒人风格

1 公共类单例{

23 /* 持有一个私有静态实例以防止它被引用。这里赋值为null,实现延迟加法。

加载*/

4 私有静态单例实例= null;

6 /* 私有构造函数,防止被实例化*/

7 私有单例() {

8}

10 /* 1:惰性风格,静态工程方法,创建实例*/

11 公共静态单例 getInstance() {

12 if (实例== null) {

13 实例 = new Singleton();

14}

15 返回实例;

16}

17}

(二)饿汉式

1 公共类单例{

3 /* 持有一个私有静态实例,防止被引用*/

4 私有静态Singleton实例 = new Singleton();

6 /* 私有构造函数以防止实例化*/

7 私有单例() {

8}

10 /* 1:惰性风格,静态工程方法,创建实例*/

11 公共静态单例 getInstance() {

12 返回实例;

13}

14}

使用场景:

1、需要生成唯一序列号的环境; 2. 整个项目的共享访问点或共享数据,例如网页上的计数

不用将每次刷新记录到数据库中,而是使用单例模式来保留计数器值并

确保它是线程安全的;

3、创建对象需要太多资源,比如访问IO、数据库资源;

4、在需要定义大量静态常量和静态方法(如工具类)的环境中,可以使用单例模式

(当然也可以直接声明为static)。

2、工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂

方法允许将类的实例化推迟到其子类。

界面

1 公共接口 Fruit {

2 公共无效打印();

3}

4 2个实现类

6 公共类苹果实现Fruit{

8 @覆盖

9 公共无效打印(){

10 System.out.println("我是苹果");

11}

12

13}

14 公共类Orange实现Fruit{

15

16 @覆盖

17 公共无效打印(){

18 System.out.println("我是一个橙子");

19}

20

21 }

工厂类 1 公共类 FruitFactory {

2 公共水果产品(字符串类型){

3 if(type.equals("苹果")){

4 返回new Apple();

5 }else if(type.equals("orange")){

6 返回新Orange();

7}其他{

8 System.out.println("请输入正确的类型!");

9 返回空值;

10}

11}

12}

使用场景:jdbc连接数据库、硬件访问、减少对象创建和销毁

3、抽象工厂模式:提供一个接口,用于创建一组相关或相互依赖的对象,而无需指定

定义他们的具体类。

与工厂模式相比,我们可以添加新的产品类别(只需要实现产品接口),并且只需要添加新的

通过添加工厂类,客户端可以轻松调用新产品的代码。

1 个接口食物{}

2 A 类实现食物{}

3 B 类实现 food{}

4 接口 Produce{ food get();}

5类FactoryForA实现了product{

6 @覆盖

7 公共食物 get() {

8 返回新的A();

9}

10}

11类FactoryForB实现了product{

12 @覆盖

13 公共食物 get() {

14 返回新B();

15}

16 }17 公共类 AbstractFactory {

18 public void ClientCode(字符串名称){

19 食物 x= new FactoryForA().get();

20 x = new FactoryForB().get();

21 }

22 }

使用场景:一族对象(或一组不相关的对象)都具有相同的约束。

当涉及到不同的操作系统时,可以考虑使用抽象工厂模式。

4. Builder模式:将复杂对象的构造与其表示分离,以便相同的构造过程可以

创建不同的表示。

1 公共类构建{

2 静态类Student{

3 字符串名称 = null ;

4 整数 = ‐1 ;

5 字符串性别 = null ;

6名公共学生(Builder建造者)

7 {

8 this.name=builder.name;

9 this.number=builder.number;

10 this.sex=builder.sex;

11}

12 静态类生成器{

13 字符串名称 = null ;

14 整数 = ‐1 ;

15 字符串性别 = null ;

16 公共生成器 setName(字符串名称){

17 this.name=名称;

18 返回这个;

19}

20 公共生成器 setNumber(int number){

21 this.number=number;

22 返回这个;

23 }

24 public Builder setSex(String sex){25 this.sex=sex;

26 返回这个;

27}

28 公共学生构建(){

29 返回新的Student(this);

30}

31

32}

33}

34 public static void main(String[] args) {

35 Student A=new Student.Builder().setName("张

三").setNumber(1).build();

36 Student B=new Student.Builder().setSex("男").setName("李

4").build();

37 System.out.println(A.姓名+" "+A.号码+" "+A.性别);

38 System.out.println(B.姓名+" "+B.号码+" "+B.性别);

39}

40}

使用场景:

1、当同一个方法但不同的执行顺序产生不同的事件结果时,可以使用构建器模型

模式。

2. 多个组件或零件可以组装成一个对象,但运行结果不同。

,可以使用该模式。

3、产品类非常复杂,或者产品类中不同的调用序列产生不同的效率。在这种情况下

使用构建器模式是完美的。

5.原型模式:使用原型实例来指定要创建的对象类型,并通过复制这些原型来创建新的对象

目的。

1 公共类 Prototype 实现 Cloneable{

2 私有字符串名称;

3 公共字符串 getName() {

4 返回姓名;

5}

6 公共无效setName(字符串名称){

7 this.name = 名称;8 }

9 @覆盖

10 受保护的对象克隆() {

11 尝试{

12 返回 super.clone();

13 } catch (CloneNotSupportedException e) {

14 e.printStackTrace();

15}终于{

16 返回空值;

17}

18}

19 公共静态无效主(字符串[]参数){

20 原型 pro = new 原型();

21 原型 pro1 = (原型)pro.clone();

22 }

23 }

原型模式实际上实现了Cloneable接口并重写了clone()方法。

使用原型模式的优点:

1.性能优良

原型模式是在内存中复制一个二进制流,它比直接new一个对象有更好的性能,尤其是

当循环体内生成大量对象时,原型模式更能体现其优势。

2. 逃脱构造函数的约束

这既是它的优点,也是它的缺点。如果直接复制到内存中,构造函数将不会被执行(参见

第 13.4 节)。

使用场景:

1. 资源优化场景

类初始化需要消化很多资源,包括数据、硬件资源等。

2、有性能和安全要求的场景

通过new生成对象需要非常繁琐的数据准备或者访问权限,所以可以使用原型模型

模式。

3、一个对象多个修饰符的场景。当一个对象需要被其他对象访问,并且每个调用者都可能需要修改它的值时,可以

考虑使用原型模式复制多个对象以供调用者使用。

浅拷贝和深拷贝:

浅拷贝:Object类提供的clone方法只复制对象以及对象内部的数组和引用

该对象没有被复制,但它仍然指向原始对象的内部元素地址。这种类型的复制称为浅复制。

其他原始类型如 int、long、char、string(作为原始类型)等将被复制。

贝。

注意:使用原型模式时,引用的成员变量必须满足两个条件才不会被复制: 1.

它是类的成员变量,而不是方法内的变量;其次,它必须是一个可变引用对象,而不是

原始类型或不可变对象。

深拷贝:对私有类变量进行独立的拷贝

例如:this.arrayList = (ArrayList)this.arrayList.clone();

6、适配器模式:将一个类的接口转变成客户端期望的另一个接口,从而使原来的

由于接口不匹配而无法一起工作的两个类可以一起工作。

主要可分为3种:

1.类适配:创建一个新的类,继承源类,并实现新的接口,如

1 类适配器扩展 oldClass 实现 newFunc{}

2.对象适配:创建一个新的类来维护源类的实例并实现新的接口,如

1 类适配器实现 newFunc { private oldClass oldInstance

;}

3、接口适配:创建一个新的抽象类来实现旧的接口方法。例如

1 抽象类适配器实现oldClassFunc { void

newFunc();}

使用场景:

当您有动力修改已经投入生产的接口时,适配器模式可能是最适合您的模式。比较

如果系统进行扩展,需要使用现有的或新创建的类,但该类不满足系统的接口。

嘴,我该怎么办?使用适配器模式,我们的示例中也提到了这一点。

7、装饰者模式:动态地给一个对象添加一些额外的职责。在增加功能、装饰方面

容器模式比生成子类更加灵活 1 interface Source{ void method();}

2 公共类Decorator实现Source{

3.私人Source源码;

4 公共无效装饰1(){

5 System.out.println("装饰");

6}

7 @覆盖

8 公共无效方法(){

9 装饰1();

10 源.method();

11}

12}

使用场景:

1、需要扩展类的功能或者给类添加额外的功能。

2、需要动态地给一个对象添加功能,并且这些功能是可以动态撤销的。

3、如果需要对一批兄弟进行修改或添加功能,当然装饰模式是首选。

8、代理模式:为其他对象提供代理来控制对该对象的访问。

1个接口来源{

2 无效方法();

3}

4 类 OldClass 实现 Source{

5 @覆盖

6 公共无效方法(){

7}

8}

9类Proxy实现Source{

10 private Source source = new OldClass();

11 无效 doSomething(){}

12 @覆盖

13 公共无效方法(){

14 new Class1().Func1();

15. 源方法();

16 new Class2().Func2();

17 doSomething();18 }

19}

9. 中介者模式:使用中介者对象来封装一系列对象交互。中介者消除了每个对象的需要

显式交互,以便它们松散耦合,并且可以独立更改它们的交互。

1 公共抽象类Mediator {

2 //定义同事类

3 受保护的ConcreteColleague1 c1;

4 受保护的ConcreteColleague2 c2;

5 //通过getter/setter方法注入同事类

6 公共 ConcreteColleague1 getC1() {

7 返回c1;

8}

9 公共无效 setC1(ConcreteColleague1 c1) {

10 这个.c1 = c1;

11}

12 公共 ConcreteColleague2 getC2() {

13 返回c2;

14}

15 公共无效setC2(ConcreteColleague2 c2){

16 这个.c2 = c2;

17}

18 //中介模型的业务逻辑

19 公共抽象无效 doSomething1();

20 公共抽象无效 doSomething2();

21 }

使用场景:

中介者模式适用于多个对象紧密耦合的情况。紧耦合的标准是:在类图中

出现蜘蛛网状的结构,即每个类都与其他类直接相关。

10.命令模式:将请求封装成一个对象,允许使用不同的请求

参数化、对请求进行排队或记录请求日志,可以提供命令撤消和恢复功能。

接收者角色:该角色是执行工作的角色。这里传递的命令是应该执行的Command命令角色:所有需要执行的命令都在这里声明。

Invoker调用者角色:接收命令并执行命令

1 //通用接收器类

2 公共抽象类接收器{

3 公共抽象无效 doSomething();

4}

5 //具体接收者类

6 公共类ConcreteReciver1扩展接收器{

7 //每个接收者必须处理一定的业务逻辑

8 公共无效 doSomething(){ }

9}

10 公共类ConcreteReciver2扩展接收器{

11 //每个接收者必须处理一定的业务逻辑

12 公共无效 doSomething(){ }

13}

14 //抽象Command类

15 公共抽象类命令{

16 公共抽象无效执行();

17}

18 //具体命令类

19 公共类ConcreteCommand1扩展命令{

20 //在哪个Receiver类上执行命令处理?

21 私人接收器接收器;

22 //构造函数传递接收者

23 公共ConcreteCommand1(接收器_receiver){

24 this.receiver = _receiver;

25}

26 //必须执行一个命令

27 公共无效执行(){

28 //业务处理

29 this.receiver.doSomething();

30}

31}

32 公共类ConcreteCommand2扩展命令{

33 //哪个Receiver类执行命令处理 34 private Receiver receive;

35 //构造函数传递接收者

36 公共ConcreteCommand2(接收器_receiver){

37. 接收器 = _receiver;

38}

39 //必须执行一个命令

40 公共无效执行(){

41 //业务处理

42. 接收器.doSomething();

43}

44}

45 //调用者类

46 公共类调用者{

47 私人指挥指挥;

48

49 public void setCommand(命令_command){

50 this.command = _command;

51}

52

53 公共无效行动(){

54 this.command.execute();

55}

56}

57 //场景类

58 公共类客户端{

59 public static void main(字符串[] args){

60 Invoker调用者 = new Invoker();

61 接收器receiver = new ConcreteReceiver1();

62

63 Command command = new ConcreteCommand1(receiver);

64 调用者.setCommand(命令);

65 调用者.action();

66}

67}

使用场景:命令模式可以用在被认为是命令的地方。例如,在 GUI 开发中,单击按钮

是一个命令,可以处于命令模式;模拟DOS命令时,当然也必须使用命令模式。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

26阅读