• Java设计模式(搭配代码讲解)


    Java设计模式

    一.概念

      1.什么是设计模式?

      设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。

      2.目的?

      1)代码重用性(即:相同功能代码,不用多次编写)

      2)可读性 (即:编程规范性,便于其他程序员阅读和理解)

      3)可扩展性 (即:当需要增加功能时,非常方便)

      4)可靠性 (即:增加新功能后,对原来功能没影响)

      5)使程序高内聚,低耦合

    二.七大原则

        详细代码看 https://github.com/ShawnSunVip/demos-collections/tree/main/demo-parent/demo-design/src/main/java/com/sun/principle

      1.单一职责原则

        1)概念

        即一个类应该只负责一项职责 

        2)实例 

        动物的运动方式

     1 public class SingleDemo1 {
     2     public static void main(String[] args) {
     3         Animal vehicle =new Animal();
     4         vehicle.run("马");
     5         vehicle.run("鸟");
     6         vehicle.run("鱼");
     7     }
     8 }
     9 
    10 //动物类
    11 class Animal {
    12     public void run(String vehicel) {
    13         System.out.println(vehicel+"	 在公路上跑");
    14     }
    15 } 
    View Code

        demo1  
        1.run方法违反了单一职责原则
        2.解决思路,根据不同动物对运动方式,分解成不同类     

     1 public class SingleDemo2 {
     2     public static void main(String[] args) {
     3         RoadAnimal roadAnimal = new RoadAnimal();
     4         roadAnimal.run("马");
     5 
     6         WaterAnimal waterAnimal = new WaterAnimal();
     7         waterAnimal.run("鱼");
     8 
     9         AirAnimal airAnimal = new AirAnimal();
    10         roadAnimal.run("鸟");
    11 
    12     }
    13 }
    14 
    15 //demo2
    16 class RoadAnimal {
    17     public void run(String vehicel) {
    18         System.out.println(vehicel+"	 在公路上跑");
    19     }
    20 }
    21 class WaterAnimal {
    22     public void run(String vehicel) {
    23         System.out.println(vehicel+"	 在水里游");
    24     }
    25 }
    26 class AirAnimal {
    27     public void run(String vehicel) {
    28         System.out.println(vehicel+"	 在天上飞");
    29     }
    30 }
    View Code

        demo2
        1.遵守了单一职责原则
        2.改动很大,类分解
        3.还可以怎么改?

     1 public class SingleDemo3 {
     2     public static void main(String[] args) {
     3         NewAnimal newAnimal = new NewAnimal();
     4         newAnimal.run("马");
     5         newAnimal.runWater("鱼");
     6         newAnimal.runAir("鸟");
     7     }
     8 }
     9 
    10 //demo3
    11 class NewAnimal {
    12     public void run(String vehicel) {
    13         System.out.println(vehicel+"	 在公路上跑");
    14     }
    15     public void runWater(String vehicel) {
    16         System.out.println(vehicel+"	 在水里游");
    17     }
    18     public void runAir(String vehicel) {
    19         System.out.println(vehicel+"	 在天上飞");
    20     }
    21 }
    View Code

        demo3
        1.只是在原来方法上添加方法
        2.在类上没有遵守单一职责原则,但在方法上,仍然遵守单一职责原则

        3)注意点

          降低类复杂度,一个类只负责一项职责

          提高可读性,可维护性

          降低变更引起的风险

          一般情况下,要遵守单一职责原则,只有逻辑特别简单,才可以在类级别违反单一职责原则,但至少保证方法的单一职责原则

      2.接口隔离原则

         1)概念

        客户端不应该依赖它不需要的接口,即一个类对另一个类依赖建立在最小对接口上

        2)实例

        类A通过接口依赖类C,类B通过接口依赖D

        改进前 

      1 public class SegregationDemo1 {
      2     public static void main(String[] args) {
      3         // 写个demo 类A通过接口依赖类C 类B通过接口依赖类D
      4         // 以下方法不符合接口隔离原则
      5         A a = new A();
      6         B b = new B();
      7         a.do1(new C());
      8         a.do2(new C());
      9         a.do3(new C());
     10         b.do1(new D());
     11         b.do4(new D());
     12         b.do5(new D());
     13     }
     14 }
     15 
     16 // 定义接口 有方法1,2,3,4,5
     17 interface Interface1{
     18     void method1();
     19     void method2();
     20     void method3();
     21     void method4();
     22     void method5();
     23 }
     24 
     25 // 类C实现接口
     26 class C implements  Interface1{
     27 
     28     public void method1() {
     29         System.out.println("C 实现method1");
     30     }
     31 
     32     public void method2() {
     33         System.out.println("C 实现method2");
     34     }
     35 
     36     public void method3() {
     37         System.out.println("C 实现method3");
     38     }
     39 
     40     public void method4() {
     41         System.out.println("C 实现method4");
     42     }
     43 
     44     public void method5() {
     45         System.out.println("C 实现method5");
     46     }
     47 }
     48 
     49 // 类D实现接口
     50 class D implements  Interface1 {
     51 
     52     public void method1() {
     53         System.out.println("D 实现method1");
     54     }
     55 
     56     public void method2() {
     57         System.out.println("D 实现method2");
     58     }
     59 
     60     public void method3() {
     61         System.out.println("D 实现method3");
     62     }
     63 
     64     public void method4() {
     65         System.out.println("D 实现method4");
     66     }
     67 
     68     public void method5() {
     69         System.out.println("D 实现method5");
     70     }
     71 }
     72 
     73 // 类A 依赖 C的方法1,2,3
     74 class A {
     75 
     76     public void do1(Interface1 i) {
     77         i.method1();
     78     }
     79 
     80     public void do2(Interface1 i) {
     81         i.method2();
     82     }
     83 
     84     public void do3(Interface1 i) {
     85         i.method3();
     86     }
     87 
     88 
     89 }
     90 
     91 // 类B 依赖 D的方法1,4,5
     92 class B {
     93 
     94     public void do1(Interface1 i) {
     95         i.method1();
     96     }
     97 
     98     public void do4(Interface1 i) {
     99         i.method4();
    100     }
    101 
    102     public void do5(Interface1 i) {
    103         i.method5();
    104     }
    105 }
    View Code  

        改进后 

     1 public class SegregationDemo2 {
     2     public static void main(String[] args) {
     3         // 改进
     4         A1 a = new A1();
     5         B1 b = new B1();
     6         a.do1(new C1());
     7         a.do2(new C1());
     8         a.do3(new C1());
     9         b.do1(new D1());
    10         b.do4(new D1());
    11         b.do5(new D1());
    12     }
    13 }
    14 
    15 // 定义接口11 有方法1
    16 interface Interface11{
    17     void method1();
    18 }
    19 
    20 // 定义接口12 有方法2,3
    21 interface Interface12{
    22     void method2();
    23     void method3();
    24 }
    25 
    26 // 定义接口13 有方法4,5
    27 interface Interface13{
    28     void method4();
    29     void method5();
    30 }
    31 
    32 // 类C实现接口11和12
    33 class C1 implements Interface11,Interface12{
    34 
    35     public void method1() {
    36         System.out.println("C 实现method1");
    37     }
    38 
    39     public void method2() {
    40         System.out.println("C 实现method2");
    41     }
    42 
    43     public void method3() {
    44         System.out.println("C 实现method3");
    45     }
    46 }
    47 
    48 // 类D实现接口11,13
    49 class D1 implements  Interface11,Interface13 {
    50 
    51     public void method1() {
    52         System.out.println("D 实现method1");
    53     }
    54 
    55     public void method4() {
    56         System.out.println("D 实现method4");
    57     }
    58 
    59     public void method5() {
    60         System.out.println("D 实现method5");
    61     }
    62 }
    63 
    64 // 类A 依赖 C的方法1,2,3
    65 class A1 {
    66 
    67     public void do1(Interface11 i) {
    68         i.method1();
    69     }
    70 
    71     public void do2(Interface12 i) {
    72         i.method2();
    73     }
    74 
    75     public void do3(Interface12 i) {
    76         i.method3();
    77     }
    78 
    79 
    80 }
    81 
    82 // 类B 依赖 D的方法1,4,5
    83 class B1 {
    84 
    85     public void do1(Interface11 i) {
    86         i.method1();
    87     }
    88 
    89     public void do4(Interface13 i) {
    90         i.method4();
    91     }
    92 
    93     public void do5(Interface13 i) {
    94         i.method5();
    95     }
    96 }
    View Code

      3.依赖倒置原则

         1)概念

        程序要依赖抽象接口,不用依赖于具体实现

        2)实例   

     1 public class InversionDemo1 {
     2     public static void main(String[] args) {
     3         Person person = new Person();
     4         person.receive(new Email());
     5     }
     6 }
     7 
     8 class Email {
     9     public String getMessage(){
    10         return "获得邮件";
    11     }
    12 }
    13 
    14 class Person {
    15     public void receive(Email e){
    16         System.out.println(e.getMessage());
    17     }
    18 }
    View Code

        demo1 简单容易

        但是如果获取对象是微信,短信,那么需要新增类,同时Person类也需要增加相应接收方法。怎么改进??? 

     1 public class InversionDemo2 {
     2     public static void main(String[] args) {
     3         NewPerson person = new NewPerson();
     4         person.receive(new Email2());
     5         person.receive(new Weixin());
     6     }
     7 }
     8 
     9 interface IReceiver {
    10     String getMessage();
    11 }
    12 
    13 class Email2 implements IReceiver {
    14     public String getMessage() {
    15         return "获得邮件消息";
    16     }
    17 }
    18 
    19 class Weixin implements IReceiver {
    20     public String getMessage() {
    21         return "获得微信消息";
    22     }
    23 }
    24 
    25 class NewPerson {
    26     public void receive(IReceiver e){
    27         System.out.println(e.getMessage());
    28     }
    29 }
    View Code

        3)总结

        高层模块不应该依赖低层模块,二者都应该依赖其抽象

        抽象不应该依赖细节,细节应该依赖抽象

        中心思想是面向接口编程

        相对于细节都多变性,抽象要稳定都多,以抽象为基础搭建多架构比以细节为基础多架构更稳定。抽象即接口或抽象类,细节即具体的实现类

        用接口或抽象类目的是制定规范,而不设计具体操作,把展示细节交给实现类完成

        4)扩展 

        依赖倒置的三种方法

      1 public class InversionDemo3 {
      2     public static void main(String[] args) {
      3         // 方式一
      4         Tourism tourism = new Tourism();
      5         tourism.ride(new Bus());
      6 
      7         // 方式二
      8           Tourism tourism = new Tourism(new AirCraft());
      9           tourism.ride();
     10         // 方式三
     11           Tourism tourism = new Tourism();
     12           tourism.setTraffic(new Bus());
     13           tourism.ride();
     14     }
     15 }
     16 
     17 // 方式1。接口传递
     18 //旅行
     19 interface ITourism {
     20     public void ride(ITraffic i);
     21 }
     22 
     23 // 交通
     24 interface ITraffic {
     25     public void tool();
     26 }
     27 
     28 //大巴
     29 class Bus implements ITraffic {
     30     public void tool() {
     31         System.out.println("乘大巴旅行");
     32     }
     33 }
     34 
     35 //飞机
     36 class AirCraft implements ITraffic {
     37     public void tool() {
     38         System.out.println("乘飞机旅行");
     39     }
     40 }
     41 
     42 // 旅行类
     43 class Tourism implements ITourism {
     44     public void ride(ITraffic t) {
     45         t.tool();
     46     }
     47 }
     48 
     49 
     50 //方式2 构造
     51 interface ITourism {
     52     public void ride();
     53 }
     54 // 交通
     55 interface ITraffic {
     56     public void tool();
     57 }
     58 
     59 //大巴
     60 class Bus implements ITraffic{
     61     public void tool() {
     62         System.out.println("乘大巴旅行");
     63    }
     64 }
     65 
     66 //飞机
     67 class AirCraft implements ITraffic{
     68     public void tool() {
     69         System.out.println("乘飞机旅行");
     70     }
     71 }
     72 
     73 // 旅行类
     74 class Tourism implements ITourism {
     75     public ITraffic t;
     76     public Tourism (ITraffic t){
     77         this.t =t;
     78     }
     79     public void ride() {
     80         t.tool();
     81     }
     82 }
     83 
     84 // 方式三 Setter注入
     85 interface ITourism {
     86    public void ride();
     87     public void setTraffic(ITraffic t);
     88 }
     89 // 交通
     90 interface ITraffic {
     91     public void tool();
     92 }
     93 
     94 //大巴
     95 class Bus implements ITraffic{
     96     public void tool() {
     97         System.out.println("乘大巴旅行");
     98     }
     99 }
    100 
    101 ////飞机
    102 class AirCraft implements ITraffic{
    103     public void tool() {
    104         System.out.println("乘飞机旅行");
    105     }
    106 }
    107 
    108 // 旅行类
    109 class Tourism implements ITourism {
    110     private ITraffic t;
    111     public void setTraffic(ITraffic t) {
    112         this.t =t;
    113     }
    114     public void ride() {
    115         t.tool();
    116     }
    117 }
    View Code

       

      4.里氏替换原则

        1)概念

        子类可以扩展父类功能,但不能改变父类原有功能。将一个基类对象替换成它子类,程序不会产生任何错误和异常

        2)实例 

     1 public class RichterReplaceDemo1 {
     2     public static void main(String[] args) {
     3         A a = new A();
     4         System.out.println("8+1:"+a.method(8, 1));
     5 
     6         B b = new B();
     7         System.out.println("8+1:"+b.method(8,1));
     8 
     9 
    10     }
    11 }
    12 
    13 class A {
    14     public int method(int n1,int n2){
    15         return n1+n2;
    16     }
    17 }
    18 
    19 class B extends A {
    20     // 不小心重写父类方法
    21     public int method(int n1,int n2){
    22         return n1-n2;
    23     }
    24 
    25     public int method2(int n1,int n2) {
    26         return (n1+n2)*3;
    27     }
    28 }
    View Code

        B类继承A类,调用者不小心修改父类方法。怎么改进尼?建立一个更小的基类。

     1 public class RichterReplaceDemo2 {
     2     public static void main(String[] args) {
     3         A1 a = new A1();
     4         System.out.println("8+1:"+a.method(8, 1));
     5 
     6         B1 b = new B1();
     7         System.out.println("8-1:"+b.method(8,1));
     8     }
     9 }
    10 
    11 //添加一个更基础但基类
    12 class Base {
    13 
    14 }
    15 
    16 class A1 extends Base {
    17     public int method(int n1,int n2){
    18         return n1+n2;
    19     }
    20 }
    21 
    22 // B类不在继承A,调用功能很明确,调用者不会改错
    23 class B1 extends Base {
    24     public int method(int n1,int n2){
    25         return n1-n2;
    26     }
    27 
    28     public int method2(int n1,int n2) {
    29         return (n1+n2)*3;
    30     }
    31 }
    View Code   

     

      5.开闭原则

        1)概念

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

        2)实例 

     1 public class OpenCloseDemo1 {
     2     public static void main(String[] args) {
     3         BackHome backHome = new BackHome();
     4         backHome.backHome(new Walk());
     5         backHome.backHome(new Car());
     6     }
     7 }
     8 
     9 // 回家
    10 class BackHome {
    11     public void backHome(Back b){
    12         if(b.type ==1){
    13             walk();
    14         }else if (b.type ==2){
    15             car();
    16         }
    17     }
    18 
    19     public void walk(){
    20         System.out.println("步行回家");
    21     }
    22 
    23     public void car(){
    24         System.out.println("开车回家");
    25     }
    26 }
    27 // 基类
    28 class Back {
    29     int type;
    30 }
    31 //步行
    32 class Walk extends Back{
    33     Walk(){
    34         super.type=1;
    35     }
    36 }
    37 //开车
    38 class Car extends Back{
    39     Car(){
    40         super.type=2;
    41     }
    42 }
    View Code

        优点:理解很容易

        缺点:难扩展,违反开闭原则

        改进:基类改成抽象类 并提供抽象方法

     1 public class OpenCloseDemo2 {
     2     public static void main(String[] args) {
     3         NewBackHome newBackHome = new NewBackHome();
     4         newBackHome.backHome(new NewWalk());
     5         newBackHome.backHome(new NewCar());
     6         newBackHome.backHome(new NewSubWay());
     7     }
     8 }
     9 
    10 // 回家
    11 class NewBackHome {
    12     public void backHome(NewBack b){
    13         b.BackHome();
    14     }
    15 
    16 }
    17 // 基类-》改成抽象类
    18 abstract class NewBack {
    19     int type;
    20     public abstract void BackHome();// 抽象方法
    21 }
    22 //步行
    23 class NewWalk extends NewBack{
    24     NewWalk(){
    25         super.type=1;
    26     }
    27 
    28     public void BackHome() {
    29         System.out.println("步行回家");
    30     }
    31 }
    32 //开车
    33 class NewCar extends NewBack{
    34     NewCar(){
    35         super.type=2;
    36     }
    37 
    38     public void BackHome() {
    39         System.out.println("开车回家");
    40     }
    41 }
    42 
    43 //地铁
    44 class NewSubWay extends NewBack{
    45     NewSubWay(){
    46         super.type=3;
    47     }
    48 
    49     public void BackHome() {
    50         System.out.println("地铁回家");
    51     }
    52 }
    View Code

     

      6.迪米特法原则(最少知道原则)

        1)概念

        一个类对它依赖对类知道对越少越好,我们称成员变量,方法参数,方法返回值为直接朋友,而局部变量不是直接朋友。

        2)实例

     1 public class LodDemo1 {
     2     public static void main(String[] args) {
     3         D d = new D();
     4         d.printAll(new C());
     5     }
     6 }
     7 
     8 class A {
     9     private int id;
    10     public int getId() {
    11         return id;
    12     }
    13 
    14     public void setId(int id) {
    15         this.id = id;
    16     }
    17 }
    18 
    19 class B {
    20     private int id;
    21     public int getId() {
    22         return id;
    23     }
    24 
    25     public void setId(int id) {
    26         this.id = id;
    27     }
    28 }
    29 
    30 class C {
    31     public List<A> getAllA(){
    32         List<A> as = new ArrayList<A>();
    33         for (int i = 0; i <5 ; i++) {
    34             A a = new A();
    35             a.setId(i);
    36             as.add(a);
    37         }
    38         return as;
    39     }
    40 }
    41 
    42 class D {
    43     public List<B> getAllB(){
    44         List<B> bs = new ArrayList<B>();
    45         for (int i = 0; i <10 ; i++) {
    46             B b = new B();
    47             b.setId(i);
    48             bs.add(b);
    49         }
    50         return bs;
    51     }
    52 
    53     public void printAll(C c){
    54         List<A> allA = c.getAllA();
    55         for (A a: allA) {
    56             System.out.println("A:"+a.getId());
    57         }
    58         List<B> allB = this.getAllB();
    59         for (B b: allB) {
    60             System.out.println("B:"+b.getId());
    61         }
    62     }
    63 }
    View Code

        类D的直接朋友:类B(方法返回值) 类C(方法参数)。非直接朋友:类A  

        违法迪米特原则,怎么改进???

     1 public class LodDemo2 {
     2     public static void main(String[] args) {
     3         D1 d = new D1();
     4         d.printAll(new C1());
     5     }
     6 }
     7 
     8 class A1 {
     9     private int id;
    10     public int getId() {
    11         return id;
    12     }
    13 
    14     public void setId(int id) {
    15         this.id = id;
    16     }
    17 }
    18 
    19 class B1 {
    20     private int id;
    21     public int getId() {
    22         return id;
    23     }
    24 
    25     public void setId(int id) {
    26         this.id = id;
    27     }
    28 }
    29 
    30 class C1 {
    31     public List<A1> getAllA(){
    32         List<A1> as = new ArrayList<A1>();
    33         for (int i = 0; i <5 ; i++) {
    34             A1 a = new A1();
    35             a.setId(i);
    36             as.add(a);
    37         }
    38         return as;
    39     }
    40 
    41     public void printA(){
    42         List<A1> allA = getAllA();
    43         for (A1 a: allA) {
    44             System.out.println("A:"+a.getId());
    45         }
    46     }
    47 
    48 }
    49 
    50 class D1 {
    51     public List<B1> getAllB(){
    52         List<B1> bs = new ArrayList<B1>();
    53         for (int i = 0; i <10 ; i++) {
    54             B1 b = new B1();
    55             b.setId(i);
    56             bs.add(b);
    57         }
    58         return bs;
    59     }
    60 
    61     public void printAll(C1 c){
    62         c.printA();
    63         List<B1> allB = this.getAllB();
    64         for (B1 b: allB) {
    65             System.out.println("B:"+b.getId());
    66         }
    67     }
    68 }
    View Code

     

      7.合成复用原则

        1)概念

        尽量使用合成/聚合方式,而不是使用继承

         2)实例

     1 public class CompositeDemo1 {
     2     public static void main(String[] args) {
     3         B b = new B();
     4         b.method3();
     5     }
     6 }
     7 
     8 class A {
     9     public void method1(){
    10         System.out.println("A:method1");
    11     }
    12     
    13     public void method2(){
    14         System.out.println("A:method2");
    15     }
    16 }
    17 
    18 class B extends A {
    19     public void method3(){
    20         method1();
    21     }
    22 }
    View Code

        为了使用类A的方法,类B去继承类A,增强了A和B的耦合

     1 public class CompositeDemo2 {
     2     public static void main(String[] args) {
     3         B1 b1 = new B1();
     4         // 解决方法1 依赖
     5         b1.method3(new A1());
     6 
     7         //解决方法2  聚合
     8         b1.setA(new A1());
     9         b1.method4();
    10 
    11         //解决方法2  组合
    12         b1.method5();
    13 
    14     }
    15 }
    16 
    17 class A1 {
    18     public void method1(){
    19         System.out.println("A:method1");
    20     }
    21 
    22     public void method2(){
    23         System.out.println("A:method2");
    24     }
    25 }
    26 
    27 class B1 {
    28     // 解决方法一
    29     public void method3(A1 a){
    30        a.method1();
    31     }
    32 
    33     // 解决方法二
    34     private A1 a;
    35 
    36     public A1 getA() {
    37         return a;
    38     }
    39 
    40     public void setA(A1 a) {
    41         this.a = a;
    42     }
    43 
    44     public void method4(){
    45         a.method1();
    46     }
    47 
    48     // 解决方法3
    49     private A1 a1 = new A1();
    50     public void method5(){
    51         a1.method1();
    52     }
    53 }
    View Code

       

      总结: 

        1.找出应用中可能变化之处,把它独立出来。

        2.针对接口编程,而不是实现编程

        3.为了交互设计之间松耦合设计

     

    三.二十三种设计模式

     1.创建型模式

      1)单例模式

        详细代码看https://github.com/ShawnSunVip/demos-collections/tree/main/demo-parent/demo-design/src/main/java/com/sun/singleton

        1⃣️饿汉式 静态常量

          优点:类加载就实例化,避免线程同步

          缺点:如果类没被使用,则导致内存浪费    

     1 class Sigleton01 {
     2     // 私有构造器 防止被new对象
     3     private Sigleton01(){}
     4 
     5     // 内部创建对象
     6     private final static Sigleton01 instance =new Sigleton01();
     7 
     8     // 对外暴露静态公共方法
     9     public static Sigleton01 getInstance(){
    10         return instance;
    11     }
    12 }
    View Code

         2⃣️饿汉式 静态代码块

          优缺点同上

     1 class Singleton02{
     2     private Singleton02(){}
     3 
     4     private static Singleton02 instance;
     5 
     6     // 静态代码块 创建实例
     7     static {
     8         instance=new Singleton02();
     9     }
    10 
    11     public static Singleton02 getInstance(){
    12         return instance;
    13     }
    14 }
    View Code

         3⃣️懒汉式 线程不安全

          优点:调用时候才实例化,节省内存

          缺点:多线程不安全

     1 class Singleton03{
     2     private Singleton03(){}
     3 
     4     private static Singleton03 instance;
     5 
     6     public static Singleton03 getInstance(){
     7         if(instance ==null){
     8             instance = new Singleton03();
     9         }
    10         return instance;
    11     }
    12 }
    View Code

           4⃣️懒汉式 synchranized

         优点:线程安全

         缺点:同步效率低

     1 class Singleton04{
     2     private Singleton04(){}
     3 
     4     private static Singleton04 instance;
     5 
     6     public static synchronized Singleton04 getInstance(){
     7         if(instance ==null){
     8             instance = new Singleton04();
     9         }
    10         return instance;
    11     }
    12 }
    13 or
    14 class Singleton04{
    15     private Singleton04(){}
    16 
    17     private static Singleton04 instance;
    18 
    19     public static Singleton04 getInstance(){
    20         if(instance ==null){
    21             synchronized(Singleton04.Class){
    22                  instance = new Singleton04();           
    23             }
    24             
    25         }
    26         return instance;
    27     }
    28 }                
    View Code

                     5⃣️懒汉式 双端检锁检测(推荐)

                     优点:线程安全,同步效率高

     1 class Singleton05{
     2     private Singleton05(){}
     3 
     4     private volatile static Singleton05 instance;
     5 
     6     public static  Singleton05 getInstance(){
     7         if(instance ==null){
     8             synchronized (Singleton05.class){
     9                 if(instance ==null){
    10                     instance = new Singleton05();
    11                 }
    12             }
    13         }
    14         return instance;
    15     }
    16 }
    View Code

           6⃣️静态内部类(推荐)

           优点:线程安全,同步效率高

           原理:类的静态属性只有在第一次加载时初始化,jvm保证了线程的安全。静态内部类被装载时不会实例化,调用时候才会

     1 class Singleton06{
     2     private Singleton06(){}
     3 
     4     private static class Singleton06Instance{
     5         private static final Singleton06 INSTANCE=new Singleton06();
     6     }
     7 
     8     public static  Singleton06 getInstance(){
     9         return Singleton06Instance.INSTANCE;
    10     }
    11 }
    View Code

         7⃣️枚举(推荐)

          优点:线程安全,防反序列化重写创建对象

    1 enum Singleton07{
    2     INSTANCE;
    3 }
    View Code

           总结:

          针对一些需要频繁创建和销毁的对象使用如工具类,数据源等。

      2)抽象工厂模式

      3)原型模式

      4)建造者模式

      5)工厂模式

        本实例demo通过设计一个计算器来讲述工厂模式的实现流程。

        详细代码查看:https://github.com/ShawnSunVip/demos-collections/tree/main/demo-parent/demo-design/src/main/java/com/sun/factory

        2.结构型模式

      1)适配器模式

      2)桥接模式

      3)装饰者模式

        本实例demo通过设计人物服饰装配来讲述装饰者模式的实现流程

        详细代码查看:https://github.com/ShawnSunVip/demos-collections/tree/main/demo-parent/demo-design/src/main/java/com/sun/decorator

      4)组合模式

      5)外观模式

      6)享元模式

      7)代理模式

     3.行为型模式

      1)模板方法模式

      2)命令模式

      3)访问者模式

      4)迭代器模式

      5)观察者模式

      6)中介者模式

      7)备忘录模式

      8)解释器模式

      9)状态模式

      10)策略模式

        本实例demo通过设计一个超市的收款方式来讲述策略模式的实现流程。

        详细代码查看:https://github.com/ShawnSunVip/demos-collections/tree/main/demo-parent/demo-design/src/main/java/com/sun/strategy

      11)责任链模式

     

    持续更新...

     

  • 相关阅读:
    centos7上安装memcached以及PHP安装memcached扩展(二)
    centos7上安装memcached以及PHP安装memcached扩展(一)
    centos7上安装redis以及PHP安装redis扩展(二)
    centos7上安装redis以及PHP安装redis扩展(一)
    Redis Desktop Manager无法连接虚拟机中启动的redis服务问题排查步骤
    CentOS 7设置开机启动服务,添加自定义系统服务
    delphi 选择文件夹目录保存
    mysql drop database ERROR 2013
    delphi 在别的方法 调用keypress事件
    delphi Inc Dec用法
  • 原文地址:https://www.cnblogs.com/shawn-sun/p/13789173.html
Copyright © 2020-2023  润新知