设计模式(一)--单例模式和原型模式

一、设计模式的分类

总体来说设计模式分为三大类

创建型(5种):主要用于处理对象的创建,实例化对象:
单例,建造者,原型,工厂方法,抽象工厂

结构型(7种):处理类或对象间的组合
适配器,装饰者,结合,桥接,外观,享元,代理

行为型(11种):描述类或对象怎样进行交互和职责分配
策略,观察者,迭代器,命令,备忘录,中介者,解释器,访问者,责任链,状态,模板方法

二、设计模式的介绍

1、 单例模式

单例模式作用,保证类在内存中的对象唯一性。
适用场景:

  • 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置
  • 控制资源的情况下,方便资源之间的互相通信。如线程池等。

饿汉与懒汉的区别
前者在类装载时就实例化,后者只有在第一次被使用时才实例化。 (饿汉的优点是避免线程同步问题,缺点是即使没用到这个实例还是会加载) (懒汉的优点是实现了懒加载,但需要解决线程安全问题!)

1> 饿汉式,没有实现懒加载~

public class Singleton() {  
    private static Singleton instance = new Singleton();  
    private Singleton(){ }  
    public static Singleton getInstance() {   
        return instance;    
    }  
}  
//获取单例对象  
Singleton mSingleton = Singleton.getInstance();

2> 懒汉,不加锁 线程非安全的

public class Singleton {  
    private static Singleton instance = null;  
    private Singleton() { }  
    private static Singleton getInstance() {  
        if(instance == null) {   
            instance = new Singleton();   
        }  
        return instance;  
    }  
}

3> 懒汉,加锁

public class Singleton {  
    private static Singleton instance = null;  
    private Singleton() { }  
    private static synchronized Singleton getInstance() {  
        if(instance == null) {   
            instance = new Singleton();   
        }  
        return instance;  
    }  
}

4>、 静态内部类实现单例(推荐)

public class Singleton {  
    private Singleton() { }  
    private static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton()  
    }  
}

5>、 容器类单例模式

public class SingletonManager {  
    private static Map<String,Object> objMap = new HashMap<String,Object>();  
    private Singleton(){ }  
    public static void registerService(String key,Object instance) {  
        if(!objMap.containsKey(key)) {  
            objMap.put(key,instance);  
        }  
    }  
    public static Object getService(String key) {  
        return objMap.get(key);  
    }  
}

原型模式(Prototype)

原型模式可以通过一个对象实例确定创建对象的种类,并且通过拷贝创建新的实例。总得来说,原型模式实际上就是从一个对象创建另一个新的对象,使新的对象有具有原对象的特征。
原型模式是一种应用及其广泛的设计模式,Clone也是一种十分常见的操作,以至于在Java中,终极父类Object将Clone方法作为了所有类应具有的基本功能,并且Java也提供了Cloneable接口

创建一个原型类, 实现Cloneable 接口(该接口里面是空的,只是起标识作用),并重写clone方法(Object 方法里集成了clone方法)

import java.io.*;

public class CloneableClass implements Cloneable ,Serializable{

    public Prototype prototype; // 随便定义一个类,获取实例
    public int num;
    public String name;

    public CloneableClass(Prototype prototype,int num,String name){
        this.prototype = prototype;
        this.num = num;
        this.name = name;
    }

    public  Object clone() throws CloneNotSupportedException {
      return super.clone();
    }

}

创建一个执行类

public class CloneableDemo {

    public static void main(String[] args) throws  Exception{

        Prototype prototype = new Prototype();
        int num = 10;
        String name = "panlei";

        CloneableClass cloneableClass = new CloneableClass(prototype,num,name);
        System.out.println(cloneableClass.toString());
        CloneableClass cloneableClass1 = (CloneableClass)cloneableClass.clone();

        System.out.println(cloneableClass.prototype == cloneableClass1.prototype);
        System.out.println(cloneableClass.num == cloneableClass1.num);
        System.out.println(cloneableClass.name == cloneableClass1.name);

    }
}

打印出的结果都为True,说明clone 出的对象属性都是引用的模型的属性;

那么浅拷贝会造成什么样的后果呢?由于浅拷贝仅将字段的引用值复制给了新的字段,但是却并没有创建新的相应对象,也就是说原型和clone中的两个字段都指向了同一个对象实例。这样,我们对clone中各字段所指向对象的属性进行了修改,原型中的成员对象也会随之改变

这时候我们需要clone一个实例,操作时并且不影响原型,这种克隆模式通常称为深克隆

import java.io.*;

public class CloneableClass implements Cloneable ,Serializable{

    public Prototype prototype; // 随便定义一个类,获取实例
    public int num;
    public String name;

    public CloneableClass(Prototype prototype,int num,String name){
        this.prototype = prototype;
        this.num = num;
        this.name = name;
    }

    public  Object clone()  {
       try {
           //将对象写到流里
           ByteArrayOutputStream bos = new ByteArrayOutputStream();
           ObjectOutputStream oos = new ObjectOutputStream(bos);
           oos.writeObject(this);
           //从流里读回来
           ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
           ObjectInputStream ois = new ObjectInputStream(bis);
           return ois.readObject();
       }catch (Exception e){
           e.printStackTrace();
           return  null;
       }
    }
}

原型模式可以说是所有设计模式中最简单的一个,它没有复杂的继承体系,只需要使需要具有拷贝功能的类实现Cloneable接口并重写clone()方法即可。但它的应用却及其广泛,它将对一个对象中各个字段(不管是私有的还是共有的)的复制操作封装在了clone()方法中,这样,使用该类的用户就不需要对对象中的各个字段的细节进行了解,直接调用clone()方法就可以实现对象的拷贝,而且,通过clone()方法还可以为不同的字段设置被复制的权限,从而允许仅对可以被复制的字段进行复制。

猜你喜欢

转载自blog.csdn.net/panleiaiying/article/details/81279161