java通关整理-设计模式(单例模式、代理模式、观察者模式[引出redis、消息中间件])

java通关整理汇总-Java基础、计算机网络、数据库、设计模式、框架、算法模板、笔试


网上收集整理,仅做笔记参考学习

1.单例模式

确保一个类只有一个实例,并提供该实例的全局访问点。

优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。

懒汉式-线程不安全

懒汉式,顾名思义就是实例在用到的时候才去创建
1、懒汉式,线程不安全
是否 Lazy 初始化:是
是否多线程安全:否
实现难度:易

描述:这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

public class Singleton{
	private static Singleton intance;
	//构造器
	private  Singleton(){
	}
	public static Singleton getInstance(){
	if(intance == null){
		intance = new Singleton();
	}
	return intance;
	}
}
懒汉式-线程安全

区别就是是否getInstance()是否由synchronized关键字

是否多线程安全:是
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)

public class Singleton{
	private static Singleton intance;
	//构造器
	private  Singleton(){
	}
	public static synchronized Singleton getInstance(){
	if(intance == null){
		intance = new Singleton();
	}
	return intance;
	}
}
饿汉式

是否 Lazy 初始化:否
是否多线程安全:是

描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。

public class Singleton{
	private static Singleton instance = new Singleton();
	//构造器
	private Singleton(){}

	public static Singleton getInstance(){
		return instance;
	}
}

2.代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。

缺点:
1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

1.创建一个Image类

public interface  Image {

    void display();
}

2.1创建Image类的实现类ImpImage

public class ImpImage implements Image {
    private String fileName;

    public ImpImage(String fileName) {
        this.fileName = fileName;
        loadImage(fileName);
    }

    @Override
    public void display() {
        System.out.println("displaying " + fileName);
    }

    private void loadImage(String fileName){
        System.out.println("loading " + fileName);
    }
}

2.2创建Image类的代理实现类ImpProxyImage

public class ImpProxyImage implements Image {

    private String fileName;
    private ImpImage impImage;

    public ImpProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void display() {
        if(impImage == null){
            impImage = new ImpImage(fileName);
        }
        impImage.display();
    }
}

3.当被请求时,使用ImpProxyImage来获取ImpImage
类的对象

public class ProxyPatternDemo {
    public static void main(String[] args) {

        Image image = new ImpProxyImage("image_10");

        image.display();//第一次impImage为null,所以需要加载
        image.display();//第二次不为空,所以直接调用方法
    }
}

运行结果
第一次impImage为null,所以需要加载后,在调用方法
第二次不为空,所以直接调用方法

loading image_10
displaying image_10
displaying image_10

3. 观察者模式

观察者模式也叫发布-订阅模式,通俗的来讲,就和我们平时关注微信公众号一样,我们用户关注微信公众号,然后当微信公众号发布新信息时,就可以一个个的发布信息。使得关注的人都可以看到发布的消息。

举个最简单的例子:
观察者模式需要一个subject类,一个观察者的接口,几个观察者接口的实现类,方法测试类。观察者订阅被观察者的状态,当被观察者状态改变的时候会通知所有订阅的观察者的过程。

把下面的代码说完之后就可以引到redis的发布订阅上,然后redis说完,面试官可能就会问其他的消息队列问题,kafka等…

被观察者:

public class Subject {        
    private List<Observer> observers = new ArrayList<>();    //状态改变    
    public void setMsg(String msg) {        
        notifyAll(msg);    
    }   
     //订阅    
    public void addAttach(Observer observer) {        
        observers.add(observer);    
    }    
    //通知所有订阅的观察者    
    private void notifyAll(String msg) {        
        for (Observer observer : observers) {            
            observer.update(msg);        
        }   
    }
}

观察者接口:

public abstract class Observer {    
    public abstract void update(String msg);
}

第一个观察者:

public class F_Observer extends Observer {
    public void update(String msg) {
        System.out.println(F_Observer.class.getName() + " : " + msg);
    }
}

第二个观察者:

public class S_Observer extends Observer {
    public void update(String msg) {
        System.out.println(S_Observer.class.getName() + " : " + msg);
    }
}

第三个观察者:

public class T_Observer extends Observer {
    public void update(String msg) {
        System.out.println(T_Observer.class.getName() + " : " + msg);
    }
}

使用方法:

public class Main {    
    public static void main(String[] args) {        
        F_Observer fObserver = new F_Observer();        
        S_Observer sObserver = new S_Observer();        
        T_Observer tObserver = new T_Observer();                
        Subject subject = new Subject();        
        subject.addAttach(fObserver);        
        subject.addAttach(sObserver);        
        subject.addAttach(tObserver);                
        subject.setMsg("msg change");    
    }
}

运行结果:
test.F_Observer : msg changetest.S_Observer : msg changetest.T_Observer : msg change

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值