常见的设计模式

目录

1.为什么要学习设计模式

2.常见的设计模式

2.1单例模式

2.1.1概念

2.1.2使用场景

2.1.3优缺点

 2.1.4示例

2.2工厂模式

2.2.1 概念

2.2.2 使用场景

2.2.3 工厂方法

2.2.4 抽象工厂

2.3 责任链模式

2.3.1 概念

2.3.2 使用场景

2.3.3 类图

2.4 观察者模式(Obsever)

2.4.1 概念

2.4.2 使用场景

2.4.3 类图

2.4.4 小结


1.为什么要学习设计模式

设计模式(Design pattern)代表了最佳的实践,是很多优秀的软件开发人员的经验总结,是解决特定问题的解决方案。它并不是语法规定,也不拘泥于特定语言。 恰当的使用设计模式可以代码的可复用性,可维护性,可扩展性,健壮性及安全性,这些都是系统非常重要的非功能性需求。

设计模式的广泛使用起始于1995年,GOF(四人帮)出版的《设计模式:可复用面向对象软件基础》。

https://gitee.com/lisenaq/patterndemo.git

2.常见的设计模式

2.1单例模式

2.1.1概念

保证在内存中只有一个实

2.1.2使用场景

比如:系统配置文件的管理,这些配置文件只要使用一个单例对象进行读写即可,系统总其他地方需要使用配置信息时,只要使用该单例对象进行获取就可以了,这样便于统一管理配置信息。

2.1.3优缺点

优点:

  • 在内存中只有一个对象,节省内存空间;
  • 避免频繁的创建销毁对象,可以提高性能;
  • 避免对共享资源的多重占用,简化访问;
  • 为整个系统提供一个全局访问点。

缺点:

  • 不适用于变化频繁的对象;
  • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;

 2.1.4示例

  1. 饥饿模式
/**
 * 单例模式,饥饿加载
 */
public class SingletonDemo {

    //1. 需要有一个私有的构造函数,防止该类通过new的方式创建实例
    private SingletonDemo(){}

    //2. 饥饿模式,首先生成一个实例
    private static final SingletonDemo instance = new SingletonDemo();

    //3. 静态方法,用于获取已经生成的实例
    public static SingletonDemo getInstance() {
        return instance;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}

这种直线方式简单,且是线程安全的。

  1. 懒汉模式
  • 第一种写法:

/**
 * 单例模式: 懒汉式
 */
public class SingletonDemo02 {

    private SingletonDemo02(){}

    private static SingletonDemo02 singletonDemo02 = null;

    public static SingletonDemo02 getInstance() {

        if (singletonDemo02 == null) {
            singletonDemo02 = new SingletonDemo02();
        }

        return singletonDemo02;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}

注意: 这种方式在多线程访问时会有问题。

  • 第二种写法:
/**
 * 单例模式: 懒汉式,线程安全,但性能较低
 */
public class SingletonDemo03 {

    private SingletonDemo03() {
    }

    private static SingletonDemo03 singletonDemo03 = null;

    public static synchronized SingletonDemo03 getInstance(){
        if(singletonDemo03 == null) {
            singletonDemo03 = new SingletonDemo03();
        }
        return singletonDemo03;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}
  • 第三种写法
public class SingletonDemo03 {

    private SingletonDemo03() {
    }

    private static SingletonDemo03 singletonDemo03 = null;

    public static  SingletonDemo03 getInstance(){
        //系统减小同步块来提升性能,可以吗?
        if(singletonDemo03 == null) {
            synchronized (SingletonDemo03.class) {
                singletonDemo03 = new SingletonDemo03();
            }
        }
        return singletonDemo03;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}

该方式依然会有线程安全问题

  • 第四种写法
/**
 * 单例模式: 懒汉式,双重检查单例
 */
public class SingletonDemo03 {

    private SingletonDemo03(){
    }

    private static SingletonDemo03 singletonDemo03 = null;

    public static  SingletonDemo03 getInstance(){
        //减小同步块,并使用双重检查来保证线程安装,可以吗?
        if(singletonDemo03 == null) {
            synchronized (SingletonDemo03.class) {
                if(singletonDemo03 == null) {
                    singletonDemo03 = new SingletonDemo03();
                }
            }
        }
        return singletonDemo03;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}
  • 第五种写法
/**
 * 单例模式: 懒加载, 线程安全
 */
public class SingletonDemo04 {

    //阻止外部实例化
    private SingletonDemo04(){
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //使用静态内部类来使用一个SingletonDemo04对象
    private static class SingletonDemoHolder {
        private final static SingletonDemo04 instance = new SingletonDemo04();
    }

    public static SingletonDemo04 getInstance() {
        return SingletonDemoHolder.instance;
    }

    public String hello(String name) {
        return "hello " + name;
    }

}
  • 第六种写法
public enum  SingletonDemo05 {

    INSTANCE;

    public String hello(String name) {
        return "hello " + name;
    }
	
}

可以保证单例,且线程安全

2.2工厂模式

2.2.1 概念

用于产生对象的方法或者式类,称之为工厂。 上面所讲到的单例模式也可以看作为一个特殊的工厂。

2.2.2 使用场景

为什么需要工作模式,原来使用new的方式感觉也很简单,且好懂?

使用工厂的原因是我们可以通过工厂模式,来集中控制对象的创建过程,这样可以给设计带来更多的灵活性。

比如:spring的IOC容器就是工厂模式的经典实现。

2.2.3 工厂方法

用于生产指定系列的对象。已鸭子为例,鸭子有真的鸭子,橡皮鸭,电子玩具鸭等。如何能方便的创建出各种鸭子,并将创建过程控制起来,以便于以后的维护和扩展?

类图:

2.2.4 抽象工厂

用于生成指定产品族,一个产品族中包括多种产品。例如:
我们都比较熟悉的电脑制造相关行业,有HP,罗技,联想,戴尔,近几年华为,小米也进来了,每个生产商生产的电脑又包括鼠标,键盘,屏幕等等配件。此时我们需要使用工厂模式来进行管理不同的产品族,这时使用简单工厂(也有叫作工厂方法的)已经无法满足要求,此时可以使用抽象工厂。

类图:

2.3 责任链模式

2.3.1 概念

责任链模式是一个对象的行为模式,很多对象之间形成一条链条,处理请求在这个链条上进行传递,直到责任链的上的某个对象决定处理请求(也可扩展为几个对象处理),这个过程对于用户来说是透明的,也就是说用户并不需要知道是责任链上的哪个对象处理的请求,对请求是否处理由链条上的对象自己决定。

为了便于理解我们可以想象一下击鼓传花的游戏。

2.3.2 使用场景

web容器中的过滤器算是责任链模式的一个经典场景。另外举个例子:当在论坛上提交内容时,论坛系统需要对一些关键词进行处理,看看有没有包含一些敏感词汇,而这些敏感词汇我们可以使用责任链模式进行处理。

2.3.3 类图

2.4 观察者模式(Obsever)

2.4.1 概念

观察者模式是对象的行为模式,有时也称为“发布/订阅模式”或者“监听器模式”。

观察者模式定义了观察者和被观察者之间的一点多的关系,让多个观察者对象可以响应一个被观察者对象。

2.4.2 使用场景

比较经典的使用场景,比如:java中的swing包中对事件的处理。浏览器对鼠标,键盘等事件的处理等, spring中的事件发布机制也是使用该模式。

2.4.3 类图

2.4.4 小结

观察者模式是使用的非常广泛,比如:Listener,Hook,Callback等等,其实都是观察者的一种应用,名称叫法不同而已,思路基本相同。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值