设计模式学习笔记03-Singleton模式和Adapter模式

本文主要是看了《设计模式》做的笔记和思考,在此分享仅代表个人观点,如有不对的地方欢迎批评和指正。

Singleton(单例)模式

基础

中心思想是全局只有一个该类的实例,相比全局变量它也有优势:单例模式不会污染命名空间。这种模式是巧妙地利用机制保证了其实例的唯一性,比如我们Java教材上的一个例子:

class Sun{
    private static Sun sun;
    protectc Sun(){}
    public static Sun initialize(){
        if(sun == null){
            sun = new Sun();
        }
        return sun;
    }
}

使用时如下:

Sun onlyOne = Sun::initialize();

此处将Sun的构造函数隐藏了起来,并提供了静态方法initialize获取Sun对象,这个Sun对象是静态的,可以保证每次调用initialize都是返回。

Java中的Protected

由于Java奇怪的权限制度,Protected修饰的构造方法将导致同一个包下的其他类可见,若使用Private修饰则子类也不可见,无法完成实例化。因此在同一个包下,使用Protected有可能出现直接new出单例的风险,但是,通过initialize()得到的对象是不受影响的,因为它是一个静态变量,从这个角度来说,单例也没有完全被破坏。

单例模式在多线程下

感谢网友的提醒并提供了他的博客供我参考,多线程下,若两个线程同时调用initialize()并都发现此时sun(上面的代码)为空,那么就有可能破坏单例,比较好的办法是加同步锁,如下所示。

public static synchronized Sun initialize(){
    if(sun == null){
        sun = new Sun();
    }
    return sun;
}

等同于:

public static Sun initialize(){
    synchronized(Sun.class){
        ...
    }
}

不过这样的声明可能影响效率(如果这个构造方法很大的话),因此可以选择使用同步代码块解决,并且给它个锁对象。其中,byte[0]就是个开销很小的锁对象,参考这篇文章得到。

class Sun{
    private static byte[] lock = new byte[0];
    public static Sun initialize(){
        synchronized(lock){
            if(sun == null){
                sun = new Sun();
            }
            return sun;
        }
    }
}

Adapter(适配器)模式

基础

该模式的作用是为了“使得原本由于接口不兼容而不能一起工作的那些类可以一起工作”,即将不兼容问题通过一个中间人解决。该模式有两种类型:类适配器、对象适配器。相比之下,个人觉得对象适配器更加灵活,也更加常见(Android中经常需要实现各种BaseAdapter)

类适配器

假设A、B是两个不兼容的接口(因为Java中不能多继承),C为类,则C会同时实现A、B两接口,并解决不兼容问题。效果是以后使用时只用C类就好,此时C是类适配器。

对象适配器

假设A、B是两个不兼容的接口,C为类,C实现了B接口,使用时需要将C实例化,C的对象负责向A提供其能够接收的数据,这个C的对象为对象适配器。有点像用电器和插座,你为了让你的用电器能用上全世界的插座,你会买电压转换器。示例代码如下:

interface A {
    showData();
}
interface B {
    int getCount();
    Object getData(int pos);
}

class C implements B{
    @override
    int getCount(){
        // 返回数据总数
        return dataSize;
    }
    @override
    Object getData(int pos){
        // 从列表中获取相应位置的数据,这里是TopicData的对象
        return list.get(pos);
    }
}

// 该类是用来展示帖子
class Topic implements A{
    private B adapter;
    void setAdapter(B adapter){
        this.adapter = adapter;
    }

    @override
    void showData(){
        if(adapter == null){
            return;
        }
        allNum = adapter.getCount();
        // 根据总数产生相应数量的显示框
        ...
        for(i = 0;i < allNum; i++){
            // 将帖子的信息放入显示框内
            TopicData topicData = (TopicData) adapter.get(i);
            topicView.setData(topicData);    
        }
    }
}

总结

Singleon(单例)模式旨在利用机制控制类的实例化过程以及其对象的数量,同时能够避免使用“全局变量”。Adapter(适配器)模式的目的是打通两个接口间的交互,解决兼容性问题的同时,保证了交互双方代码的稳定,同时该模式也能够使得结构上具有较大的灵活性。

谢谢您的观看。

你可能感兴趣的:(设计模式学习笔记03-Singleton模式和Adapter模式)