常用的设计模式

设计模式:所谓的设计模式就是在大量的实践和理论总结后优选出来的代码结构、编程风格、解决问题的思考方式,也就是我们面对具体应用场景时的编程“套路”。通用的设计模式主要分为三种,即创建型模式、结构型模式、行为型模式。

1. 三种模式

 

 

 

 

 

 

 

2. 常用的设计模式

2.1. 单例设计模式(singleton)

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要也不能实例化该类的对象。优点是在内存里只有一个实例,减少了内存的开销,缺点是不能继承,不满足多态性。注意,外部可能有多个变量名,但是其地址都一样。同时,因为外部不能new对象,而外部又要获取对象,导致我们只能通过类名来获取对象,即实例化方法和对象都要是静态的,这样外部才能取得对象。

2.1.1 饿汉式

一开始就实例化对象,不管后面有没有用到。

优点:线程安全

缺点:对象加载时间长

例子:

 1 class Connection{
 2     // 1. 构造函数私有,不允许外部调用  
 3     private Connection(){}
 4     // 2. 创建静态私有空对象
 5       private static Connection conn = null;
 6     // 3. 公共的静态的获取实例的方法
 7       public static Connnection getInstance(){
 8             if(conn = null) {
 9                   conn = new Connnection();  //第一次创建对象
10             }
11             return conn;
12       }   
13 }

解释:

为什么要构造器设置为private: 这样类的外部不能new对象,而内部可以。

为什么要是静态方法:因为外部不能创建对象,那么只能通过类名来调用方法,用类名来调用方法,就是静态方法了。当然,既然是静态方法,它只能调用静态结构,那么该类对象的变量也应该是静态的。

 

 

懒汉式:等到需要用到对象才创建对象。对象的生命周期短,节省开销。

线程安全的例子:

 1 public class Singleton {  
 2     private volatile static Singleton singleton;  
 3     private Singleton (){}  
 4     public static Singleton getSingleton() {  
 5     if (singleton == null) {  
 6         synchronized (Singleton.class) {  
 7         if (singleton == null) {  
 8             singleton = new Singleton();  
 9         }  
10         }  
11     }  
12     return singleton;  
13     }  
14 }

2.2 模板设计模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。实际执行的是子类的重写的方法。这种类型的设计模式属于行为型模式。模板模式是抽象类多态性的应用。

解决的问题:一些场景下,一部分的流程是确定的,另外一部分的流程是不确定的。那么,就把不确定的部分暴露出去,让子类实现。这部分不确定的部分会被组合进总的流程中,不确定的部分就像钩子一样,挂在哪个子类上,就执行子类的实现。

例子:银行业务

 1 abstract public class BankTemplate {
 2     public void takeNumber(){
 3         System.out.println("取号码");
 4     }
 5     public void evalute(){
 6         System.out.println("业务完成,请评价服务");
 7     }
 8     public abstract void transact();  //业务方法,即钩子方法,让子类去实现;指定是抽象的,让子类必须去重写
 9 
10     //模板方法,将所有流程组合起来,不确定的部分暴露给子类
11     public void process();
12         this.takeNumber();
13 
14         this.transact();   //钩子方法,由子类具体实现
15 
16         this.evalute();
17 
18     }
19 
20 }
21 
22 //抽象类的子类,实现钩子方法
23 class Deposit extends BankTemplate{   
24 
25     public void transact() {
26         System.out.println("存钱");  
27     }
28 }
29 
30 
31 //测试类
32 public class TemplateTest {
33     public static void main(String[] args) {
34         BankTemplate t1 = new Deposit();
35         t1.process();    //子类对象调用总的流程方法。其中,钩子方法被重写,执行子类的业务
36     }
37 }

 

2.3 代理模式

 

 就是通过一个代理类间接地访问被代理类的对象。(类比:明星与经纪人)

2.4 工厂模式

实现创建者与调用者的分离,即将创建对象的具体实现屏蔽隔离,以解耦软件开发。

简单工厂模式:也称之为静态工厂模式,通过类名可调用函数。

                         如:建一个用于创建对象的工厂类:XxxFactory()。 然后,调用该工厂类的方法获取对象。 如 Car car = CarFactory("XXX");

工厂方法模式:定义一个工厂接口,让多个工厂类去实现该接口,不同工厂类用于获取不同的对象。

抽象工厂模式:抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

例子:来自:https://www.runoob.com

 

 

 应用:spring框架用到了上面几种设计模式

(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
(2)单例模式:Bean默认为单例模式。
(3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
(4)模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
(5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它
的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener

 

posted @ 2020-08-22 01:01  dqwang_i33  阅读(247)  评论(0)    收藏  举报