设计模式

一、设计模式大致分为三大类:创建型模式、结构型模式和行为型模式。

1、单例模式:保证一个类只有一个实例,提供一个访问它的全局访问点。

<懒汉模式>
优点->是延迟加载(需要的时候才去加载),适合单线程操作
缺点->是非线程安全的,在多线程中很容易出现不同步的情况

public class Singleton {  
    /* 私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  

    /* 私有构造方法,防止被实例化 */  
    private Singleton() {}  

    /* 1:懒汉式,静态工程方法,创建实例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

双重线程检查
优点->延迟加载,线程安全
缺点->写法复杂,不简洁

public class SingletonInner { 
    /* volatile保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象*/ 
    private static volatile SingletonInner sInst = null;  

    /* 私有的构造函数 */  
    private SingletonInner() {}  

    public static SingletonInner getInstance() {  
        SingletonInner inst = sInst;  // 创建临时变量
        if (inst == null) {
            synchronized (SingletonInner.class) {
                inst = sInst;
                if (inst == null) {
                    inst = new SingletonInner();
                    sInst = inst;
                }
            }
        }
        return inst;  // 注意这里返回的是临时变量
    }

内部类的实现
优点:延迟加载,线程安全(java中class加载时互斥的),也减少了内存消耗,推荐使用内部类方式。

public class SingletonInner {  
    /* 内部类实现单例模式,延迟加载,减少内存开销 */  
    private static class SingletonHolder {  
        private static SingletonInner instance = new SingletonInner();  
    }  

    /* 私有的构造函数 */  
    private SingletonInner() {}  

    public static SingletonInner getInstance() {  
        return SingletonHolder.instance;  
    }  
}  

<饿汉模式>
优点->是线程安全的,以空间换时间

public class Singleton {
    //将构造方法私有化,不允许外部直接创建对象
    private Singleton(){}

    //创建类的唯一实例,使用private static修饰
    private static Singleton instance = new Singleton();

    //提供一个用于获取实例的方法,使用public static修饰
    public static Singleton getInstance(){
        return instance;
    }
}

2、工厂模式: 为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
<简单工厂模式Simple Factory>
又称为静态工厂方法模式,不利于产生系列产品

public class Factory{ //getClass 产生Sample 一般可使用动态类装载装入类。
    public static Sample creator(int which){ 
        if (which==1)
            return new SampleA();
        else if (which==2)
            return new SampleB();
    }
}

<工厂方法模式Factory Method>
是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。

//抽象产品角色
public interface Moveable {
    void run();
}
//具体产品角色
public class Plane implements Moveable {
    @Override
    public void run() {
        System.out.println("plane....");
    }
}
//具体产品角色
public class Broom implements Moveable {
    @Override
    public void run() {
        System.out.println("broom.....");
    }
}
//抽象工厂
public abstract class VehicleFactory {
    abstract Moveable create();
}
//具体工厂
public class PlaneFactory extends VehicleFactory{
    public Moveable create() {
    return new Plane();
    }
}
//具体工厂
public class BroomFactory extends VehicleFactory{
    public Moveable create() {
        return new Broom();
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        VehicleFactory factory = new BroomFactory();
        Moveable m = factory.create();
        m.run();
    }
}

3、观察者模式: 又叫发布-订阅(Publish/Subscribe)模式。定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

/**  
* Subject(目标,Subject):    
* 目标知道它的观察者。可以有任意多个观察者观察同一个目标。  
* 提供注册和删除观察者对象的接口。  
*/  
public interface Subject {  
    public void attach(Observer mObserver);  
    public void detach(Observer mObserver);        
    public void notice();  
}

/**  
* Observer(观察者,Observer):  
* 为那些在目标发生改变时需要获得通知的对象定义一个更新接口。   
*/  
public interface Observer {  
    public void update();  
}  

/**  
* ConcreteSubject(具体目标,Teacher)  
* 将有关状态存入各ConcreteObserve对象。  
* 当他的状态发生改变时,向他的各个观察者发出通知。   
*/  
public class Teacher implements Subject{  

    private String phone;  
    private Vector students;  

    public Teacher(){  
        phone = "";  
        students = new Vector();  
    }  

    @Override  
    public void attach(Observer mObserver) {  
        students.add(mObserver);  
    }  

    @Override  
    public void detach(Observer mObserver) {  
        students.remove(mObserver);  
    }  

    @Override  
    public void notice() {  
        for(int i=0;i<students.size();i++){  
            ((Observer)students.get(i)).update();  
        }  
    }  

    public String getPhone() {  
        return phone;  
    }  

    public void setPhone(String phone) {  
        this.phone = phone;  
        notice();  
    }  
}

/**  
* ConcreteObserver(具体观察者, Student):  
* 维护一个指向ConcreteSubject对象的引用。  
* 存储有关状态,这些状态应与目标的状态保持一致。  
* 实现Observer的更新接口以使自身状态与目标的状态保持一致。  
*/  
public class Student implements Observer{  

    private String name;  
    private String phone;  
    private Teacher mTeacher;  

    public Student(String name,Teacher t){  
        this.name = name;  
        mTeacher = t;  
    }  

    public void show(){  
        System.out.println("Name:"+name+"\nTeacher'sphone:" + phone);  
    }  

    @Override  
    public void update() {  
        phone = mTeacher.getPhone();  
    }  
}

/**  
* 观察者(Observer)模式测试类   
*/  
public class ObserverClient {  
    public static void main(String[] args) {  
        Vector students = new Vector();  
        Teacher t = new Teacher();  
        for(int i= 0;i<10;i++){  
            Student st = new Student("Andy.Chen"+i,t);  
            students.add(st);  
            t.attach(st);  
        }  

        System.out.println("Welcome to Andy.Chen Blog!" +"\n"   
            +"Observer Patterns." +"\n"  
            +"-------------------------------");  

        t.setPhone("12345678");  
        for(int i=0;i<3;i++)  
            ((Student)students.get(i)).show();  

        t.setPhone("87654321");  
        for(int i=0;i<3;i++)  
            ((Student)students.get(i)).show();  
    }  
}