单例、观察者、代理、备忘录、工厂
分类: java 2014-07-03 10:13 364人阅读 评论(0) 收藏 举报
一、Singleton单例模式
Singleton单例模式是最简单的设计模式,它的主要作用是保证在程序运行生命周期中,使用了单类模式的类只能有一个实例对象存在。
1、饱汉模式,声明时就创建实例对象
[java] view plaincopy
- public class Singleton1 {
- public static final Singleton1 instance = new Singleton1();
- private Singleton1(){
- }
- public static Singleton1 getInstance(){
- return instance;
- }
- }
[java] view plaincopy
- public class Singleton1 {
- public static final Singleton1 instance = new Singleton1();
- private Singleton1(){
- }
- public static Singleton1 getInstance(){
- return instance;
- }
- }
2、饿汉单类模式即延迟初始化单类方式,一般认为饱汉模式要比饿汉模式更加安全。
[java] view plaincopy
- public class Singleton2 {
- public static Singleton2 instance;
- private Singleton2(){
- }
- //延迟初始化的单类模式必须使用synchronized同步关键字,否则多线程情况下很容易产生多个实例对象
- public static synchronized Singleton2 getInstance(){
- if(null==instance){
- instance = new Singleton2();
- }
- return instance;
- }
- }
[java] view plaincopy
- public class Singleton2 {
- public static Singleton2 instance;
- private Singleton2(){
- }
- //延迟初始化的单类模式必须使用synchronized同步关键字,否则多线程情况下很容易产生多个实例对象
- public static synchronized Singleton2 getInstance(){
- if(null==instance){
- instance = new Singleton2();
- }
- return instance;
- }
- }
3、类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
[java] view plaincopy
- public class Singleton3 {
- private static class SingletonHolder {
- //静态初始化器,由JVM来保证线程安全
- private static Singleton3 instance = new Singleton3();
- }
- private Singleton3() {
- }
- public static Singleton3 getInstance() {
- return SingletonHolder.instance;
- }
- }
- //当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.instance,导致SingletonHolder类得到初始化;
- //而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,由于是静态的域,
- //因此只会被虚拟机在装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。
- //这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。
[java] view plaincopy
- public class Singleton3 {
- private static class SingletonHolder {
- //静态初始化器,由JVM来保证线程安全
- private static Singleton3 instance = new Singleton3();
- }
- private Singleton3() {
- }
- public static Singleton3 getInstance() {
- return SingletonHolder.instance;
- }
- }
- //当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.instance,导致SingletonHolder类得到初始化;
- //而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,由于是静态的域,
- //因此只会被虚拟机在装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。
- //这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。
4、用枚举,最好的实现方式
[java] view plaincopy
- public enum Singleton4 {
- INSTANCE{
- @Override
- public String doSomeThing() {
- return "单例类中的方法";
- }
- };
- public abstract String doSomeThing();
- }
[java] view plaincopy
- public enum Singleton4 {
- INSTANCE{
- @Override
- public String doSomeThing() {
- return "单例类中的方法";
- }
- };
- public abstract String doSomeThing();
- }
二、Observer观察者设计模式
Observer观察者设计模式用于将对象的变化通知给感兴趣的用户。在Observer模式中的角色为主题(subject)与观察者(observer),
观察者订阅它感兴趣的主题,一个主题可以被多个观 察者订阅,当主题的状态发生变化时,
它必须通知(notify)所有订阅它的观察者,观察者检视主题的状态变化,并作出对应的动作
[java] view plaincopy
- public class ObserverPattern {
- public static void main(String[] args) {
- Subject subject = new Subject();
- Observer1 obj1 = new Observer1();
- subject.addObserver(obj1);
- Observer2 obj2 = new Observer2();
- subject.addObserver(obj2);
- subject.change();
- }
- }
- class Subject extends Observable{
- public void change(){
- setChanged();
- String message = "我是主题,我发生了变化";
- System.out.println(message);
- notifyObservers(message);
- }
- }
- class Observer1 implements Observer {
- public void update(Observable arg0, Object arg1) {
- System.out.println(arg0+":观察者一收到了");
- }
- }
- class Observer2 implements Observer {
- public void update(Observable arg0, Object arg1) {
- System.out.println(arg0+":观察者二收到了");
- }
- }
[java] view plaincopy
- public class ObserverPattern {
- public static void main(String[] args) {
- Subject subject = new Subject();
- Observer1 obj1 = new Observer1();
- subject.addObserver(obj1);
- Observer2 obj2 = new Observer2();
- subject.addObserver(obj2);
- subject.change();
- }
- }
- class Subject extends Observable{
- public void change(){
- setChanged();
- String message = "我是主题,我发生了变化";
- System.out.println(message);
- notifyObservers(message);
- }
- }
- class Observer1 implements Observer {
- public void update(Observable arg0, Object arg1) {
- System.out.println(arg0+":观察者一收到了");
- }
- }
- class Observer2 implements Observer {
- public void update(Observable arg0, Object arg1) {
- System.out.println(arg0+":观察者二收到了");
- }
- }
输出结果:
我是主题,我发生了变化
com.hzb.observer.Subject[email protected]:观察者二收到了
[email protected]:观察者一收到了
三、Proxy代理设计模式
1、普通的代理
客户端程序->代理程序->目标程序
[java] view plaincopy
- public class ProxyGeneral {
- public static void main(String[] args){
- //客户端调用代理程序
- ProxyBase p = new ProxyProgram();
- p.f();
- }
- }
- //代理程序
- class ProxyProgram implements ProxyBase{
- private ProxyBase target;
- public ProxyProgram(){
- //目标程序
- target = new Target();
- }
- public void f(){
- System.out.println("代理程序在调用目标程序前的处理");
- target.f();
- System.out.println("代理程序在调用目标程序后的处理");
- }
- }
- <pre class="java" name="code">//目标接口
- interface ProxyBase{
- public void f();
- } </pre>//目标程序 class Target implements ProxyBase{ public void f(){ System.out.println("Target.f()"); } }
[java] view plaincopy
- public class ProxyGeneral {
- public static void main(String[] args){
- //客户端调用代理程序
- ProxyBase p = new ProxyProgram();
- p.f();
- }
- }
- //代理程序
- class ProxyProgram implements ProxyBase{
- private ProxyBase target;
- public ProxyProgram(){
- //目标程序
- target = new Target();
- }
- public void f(){
- System.out.println("代理程序在调用目标程序前的处理");
- target.f();
- System.out.println("代理程序在调用目标程序后的处理");
- }
- }
- <div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><strong>[java]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/huangzebiao007/article/details/12880067#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/huangzebiao007/article/details/12880067#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/huangzebiao007/article/details/12880067#">print</a><a target=_blank title="?" class="About" href="http://blog.csdn.net/huangzebiao007/article/details/12880067#">?</a></div></div><ol class="dp-j"><li class="alt"><span><span class="comment">//目标接口</span><span> </span></span></li><li><span><span class="keyword">interface</span><span> ProxyBase{ </span></span></li><li class="alt"><span> <span class="keyword">public</span><span> </span><span class="keyword">void</span><span> f(); </span></span></li><li><span>} </span></li></ol></div><pre class="java" style="display: none;" name="code">//目标接口
- interface ProxyBase{
- public void f();
- }
//目标程序 class Target implements ProxyBase{ public void f(){ System.out.println("Target.f()"); } }
输出结果:
代理程序在调用目标程序前的处理
Target.f()
代理程序在调用目标程序后的处理
2、动态代理,java的动态代理只能针对接口进行动态代理,即要实现动态代理的类必须实现接口
[java] view plaincopy
- public class ProxyDynamic {
- public static void main(String[] args){
- ITarget target = new TargetImpl();
- ProxyHandler handler = new ProxyHandler(target);
- //产生动态代理
- ITarget proxy = (ITarget)Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class[]{ITarget.class}, handler);
- proxy.f("arg参数");
- proxy.g();
- }
- }
- //目标接口
- interface ITarget{
- public void f(String s);
- public void g();
- }
- //接口实现类,即被代理类(目标类)
- class TargetImpl implements ITarget{
- public void f(String s){
- System.out.println("TargetImpl.f(), s=" + s);
- }
- public void g() {
- System.out.println("TargetImpl.g()");
- }
- }
- //动态代理处理类
- class ProxyHandler implements InvocationHandler{
- private Object object;
- public ProxyHandler (Object obj) {
- this.object = obj;
- }
- public Object invoke(Object proxy, Method method, Object[] args){
- System.out.println("Before mothod:" + method);
- try {
- method.invoke(this.object, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("After mothod:" + method);
- return null;
- }
- }
[java] view plaincopy
- public class ProxyDynamic {
- public static void main(String[] args){
- ITarget target = new TargetImpl();
- ProxyHandler handler = new ProxyHandler(target);
- //产生动态代理
- ITarget proxy = (ITarget)Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class[]{ITarget.class}, handler);
- proxy.f("arg参数");
- proxy.g();
- }
- }
- //目标接口
- interface ITarget{
- public void f(String s);
- public void g();
- }
- //接口实现类,即被代理类(目标类)
- class TargetImpl implements ITarget{
- public void f(String s){
- System.out.println("TargetImpl.f(), s=" + s);
- }
- public void g() {
- System.out.println("TargetImpl.g()");
- }
- }
- //动态代理处理类
- class ProxyHandler implements InvocationHandler{
- private Object object;
- public ProxyHandler (Object obj) {
- this.object = obj;
- }
- public Object invoke(Object proxy, Method method, Object[] args){
- System.out.println("Before mothod:" + method);
- try {
- method.invoke(this.object, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("After mothod:" + method);
- return null;
- }
- }
输出结果:
Before mothod:public abstract void com.hzb.proxy.ITarget.f(java.lang.String)
TargetImpl.f(), s=arg参数
After mothod:public abstract void com.hzb.proxy.ITarget.f(java.lang.String)
Before mothod:public abstract void com.hzb.proxy.ITarget.g()
TargetImpl.g()
After mothod:public abstract void com.hzb.proxy.ITarget.g()
四、Memento备忘录设计模式
Memento备忘录设计模式是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到以前保存的状态
Memento备忘录设计模式有以下3个重要角色:
Originator:需要保存内部状态的对象。
Caretaker:为Originator保存并恢复状态的对象。
Memento:存放Originator内部状态的对象。
[java] view plaincopy
- public class MementoPattern {
- public static void main(String[] args) {
- Originator originator = new Originator("State1");
- Caretaker caretaker = new Caretaker();
- caretaker.addMemento(originator.createMemento(originator.getState()));
- originator.setState("State2");
- String restore = caretaker.getMemento().getState();
- System.out.println("Current originator state=" + originator.getState()
- + ",restore state=" + restore);
- }
- }
- // Memento
- class Memento {
- private String state;
- public Memento(String state) {
- this.state = state;
- }
- public String getState() {
- return state;
- }
- }
- // Caretaker
- class Caretaker {
- private Stack<Memento> mementos = new Stack<Memento>();
- public void addMemento(Memento m) {
- mementos.push(m);
- }
- public Memento getMemento() {
- if (!mementos.empty()) {
- return mementos.pop();
- }
- return null;
- }
- }
- // Originator
- class Originator {
- private String state;
- public Originator(String state) {
- this.state = state;
- }
- public void setState(String state) {
- this.state = state;
- }
- public String getState() {
- return state;
- }
- public Memento createMemento(String state) {
- return new Memento(state);
- }
- }
[java] view plaincopy
- public class MementoPattern {
- public static void main(String[] args) {
- Originator originator = new Originator("State1");
- Caretaker caretaker = new Caretaker();
- caretaker.addMemento(originator.createMemento(originator.getState()));
- originator.setState("State2");
- String restore = caretaker.getMemento().getState();
- System.out.println("Current originator state=" + originator.getState()
- + ",restore state=" + restore);
- }
- }
- // Memento
- class Memento {
- private String state;
- public Memento(String state) {
- this.state = state;
- }
- public String getState() {
- return state;
- }
- }
- // Caretaker
- class Caretaker {
- private Stack<Memento> mementos = new Stack<Memento>();
- public void addMemento(Memento m) {
- mementos.push(m);
- }
- public Memento getMemento() {
- if (!mementos.empty()) {
- return mementos.pop();
- }
- return null;
- }
- }
- // Originator
- class Originator {
- private String state;
- public Originator(String state) {
- this.state = state;
- }
- public void setState(String state) {
- this.state = state;
- }
- public String getState() {
- return state;
- }
- public Memento createMemento(String state) {
- return new Memento(state);
- }
- }
输出结果:
Current originator state=State2,restore state=State1
五、工厂模式
1、简单工厂模式:又叫静态工厂模式,简单工厂只包括一个抽象产品类(该类可以是接口,也可以是具体的类),所有需要的产品类都是该抽象产品类的子类。简单工厂模式中工厂为具体产品工厂,产品为抽象产品,由工厂实例创建产品实例:
[java] view plaincopy
- public class FactorySimple {
- public static void draw(Shape shape) {
- shape.draw();
- }
- public static void main(String[] args) {
- try {
- draw(ShapeFactory.createShape("com.hzb.factory.Circle"));
- draw(ShapeFactory.createShape("com.hzb.factory.Rectangle"));
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- // 图形接口
- interface Shape {
- public void draw();
- }
- // 圆形
- class Circle implements Shape {
- public void draw() {
- System.out.println("Circle is drawing");
- }
- }
- // 矩形
- class Rectangle implements Shape {
- public void draw() {
- System.out.println("Rectangle is drawing");
- }
- }
- // 图形工厂
- class ShapeFactory {
- public static Shape createShape(String name) throws InstantiationException,
- IllegalAccessException, ClassNotFoundException {
- // 使用java的反射机制来产生对象实例
- return (Shape) Class.forName(name).newInstance();
- }
- }
[java] view plaincopy
- public class FactorySimple {
- public static void draw(Shape shape) {
- shape.draw();
- }
- public static void main(String[] args) {
- try {
- draw(ShapeFactory.createShape("com.hzb.factory.Circle"));
- draw(ShapeFactory.createShape("com.hzb.factory.Rectangle"));
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- // 图形接口
- interface Shape {
- public void draw();
- }
- // 圆形
- class Circle implements Shape {
- public void draw() {
- System.out.println("Circle is drawing");
- }
- }
- // 矩形
- class Rectangle implements Shape {
- public void draw() {
- System.out.println("Rectangle is drawing");
- }
- }
- // 图形工厂
- class ShapeFactory {
- public static Shape createShape(String name) throws InstantiationException,
- IllegalAccessException, ClassNotFoundException {
- // 使用java的反射机制来产生对象实例
- return (Shape) Class.forName(name).newInstance();
- }
- }
输出结果:
Circle is drawing
Rectangle is drawing
2、抽象工厂模式:抽象工厂模式中可以包括多个抽象产品类,每个抽象产品类可以产生出多个具体产品类,一个抽象工厂用于定义所需产品的组合形式,抽象工厂派生具体工厂类,这些具体工厂类就是简单工厂模式中的工厂类,具体工厂类负责具体产品实例的创建:
[java] view plaincopy
- public class FactoryAbstract {
- public static void main(String[] args) {
- // 显示一套IOS皮肤
- Skin skin = new Skin(new IOSSkinFactory());
- skin.showSkin();
- // 换一套Android的皮肤
- skin.setSkinFactory(new AndroidSkinFactory());
- skin.showSkin();
- }
- }
- //软件皮肤类
- class Skin {
- private SkinFactory skinFactory;
- public Skin(SkinFactory factory) {
- setSkinFactory(factory);
- }
- public void setSkinFactory(SkinFactory factory) {
- this.skinFactory = factory;
- }
- public void showSkin() {
- System.out.println("Style=" + skinFactory.getStyle().showStyle()
- + ", color=" + skinFactory.getColor().showColor());
- }
- }
- //抽象皮肤工厂
- interface SkinFactory {
- public Style getStyle();
- public Color getColor();
- }
- // IOS皮肤工厂
- class IOSSkinFactory implements SkinFactory {
- public Style getStyle() {
- return new IOSStyle();
- }
- public Color getColor() {
- return new IOSColor();
- }
- }
- // Android皮肤工厂
- class AndroidSkinFactory implements SkinFactory {
- public Style getStyle() {
- return new AndroidStyle();
- }
- public Color getColor() {
- return new AndroidColor();
- }
- }
- // 软件Style
- interface Style {
- public String showStyle();
- }
- // IOS style
- class IOSStyle implements Style {
- public String showStyle() {
- return "This is IOS style";
- }
- }
- // Android style
- class AndroidStyle implements Style {
- public String showStyle() {
- return "This is Android style";
- }
- }
- // 软件Color
- interface Color {
- public String showColor();
- }
- // IOS color
- class IOSColor implements Color {
- public String showColor() {
- return "This is IOS color";
- }
- }
- // Android color
- class AndroidColor implements Color {
- public String showColor() {
- return "This is Android color";
- }
- }
[java] view plaincopy
- public class FactoryAbstract {
- public static void main(String[] args) {
- // 显示一套IOS皮肤
- Skin skin = new Skin(new IOSSkinFactory());
- skin.showSkin();
- // 换一套Android的皮肤
- skin.setSkinFactory(new AndroidSkinFactory());
- skin.showSkin();
- }
- }
- //软件皮肤类
- class Skin {
- private SkinFactory skinFactory;
- public Skin(SkinFactory factory) {
- setSkinFactory(factory);
- }
- public void setSkinFactory(SkinFactory factory) {
- this.skinFactory = factory;
- }
- public void showSkin() {
- System.out.println("Style=" + skinFactory.getStyle().showStyle()
- + ", color=" + skinFactory.getColor().showColor());
- }
- }
- //抽象皮肤工厂
- interface SkinFactory {
- public Style getStyle();
- public Color getColor();
- }
- // IOS皮肤工厂
- class IOSSkinFactory implements SkinFactory {
- public Style getStyle() {
- return new IOSStyle();
- }
- public Color getColor() {
- return new IOSColor();
- }
- }
- // Android皮肤工厂
- class AndroidSkinFactory implements SkinFactory {
- public Style getStyle() {
- return new AndroidStyle();
- }
- public Color getColor() {
- return new AndroidColor();
- }
- }
- // 软件Style
- interface Style {
- public String showStyle();
- }
- // IOS style
- class IOSStyle implements Style {
- public String showStyle() {
- return "This is IOS style";
- }
- }
- // Android style
- class AndroidStyle implements Style {
- public String showStyle() {
- return "This is Android style";
- }
- }
- // 软件Color
- interface Color {
- public String showColor();
- }
- // IOS color
- class IOSColor implements Color {
- public String showColor() {
- return "This is IOS color";
- }
- }
- // Android color
- class AndroidColor implements Color {
- public String showColor() {
- return "This is Android color";
- }
- }
输出结果:
Style=This is IOS style, color=This is IOS color
Style=This is Android style, color=This is Android color
3、工厂方法模式:工厂方法中也只包含一个抽象产品类,抽象产品类可以派生出多个具体产品类。工厂方法定义一个用于创建产品的接口,让子类决定实例化哪一个类,使得类的实例化延迟到子类。
[java] view plaincopy
- public class FactoryMethod {
- public static void main(String[] args) {
- CarFactory factory = new BenzCarFactory();
- ICar car = factory.createCar();
- car.run();
- factory = new BMWCarFactory();
- car = factory.createCar();
- car.run();
- }
- }
- //抽象汽车工厂
- abstract class CarFactory {
- public abstract ICar createCar();
- }
- //奔驰车工厂
- class BenzCarFactory extends CarFactory {
- public ICar createCar() {
- return new BenzCar();
- }
- }
- //宝马车工厂
- class BMWCarFactory extends CarFactory {
- public ICar createCar() {
- return new BMWCar();
- }
- }
- // 汽车接口
- interface ICar {
- public void run();
- }
- // 奔驰车
- class BenzCar implements ICar {
- public void run() {
- System.out.println("Benz car run");
- }
- }
- // 宝马车
- class BMWCar implements ICar {
- public void run() {
- System.out.println("BMW car run");
- }
- }
[java] view plaincopy
- public class FactoryMethod {
- public static void main(String[] args) {
- CarFactory factory = new BenzCarFactory();
- ICar car = factory.createCar();
- car.run();
- factory = new BMWCarFactory();
- car = factory.createCar();
- car.run();
- }
- }
- //抽象汽车工厂
- abstract class CarFactory {
- public abstract ICar createCar();
- }
- //奔驰车工厂
- class BenzCarFactory extends CarFactory {
- public ICar createCar() {
- return new BenzCar();
- }
- }
- //宝马车工厂
- class BMWCarFactory extends CarFactory {
- public ICar createCar() {
- return new BMWCar();
- }
- }
- // 汽车接口
- interface ICar {
- public void run();
- }
- // 奔驰车
- class BenzCar implements ICar {
- public void run() {
- System.out.println("Benz car run");
- }
- }
- // 宝马车
- class BMWCar implements ICar {
- public void run() {
- System.out.println("BMW car run");
- }
- }
输出结果:
Benz car run
BMW car run
工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。
但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。工厂模式返回的实例可以不是新创建的,
返回由工厂创建好的实例也是可以的。
三种工厂模式的区别:
简单工厂 : 用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。
抽象工厂 :用来生产不同产品族(由不同产品组合成的一套产品)的全部产品,对于增加新的产品,无能为力;支持增加产品族。
工厂方法 :用来生产同一等级结构中的固定产品,支持增加任意产品。
备注:java设计模式的学习主要是参考一位牛人http://blog.csdn.net/chjttony和从网上查找到的学习资料,转载请注明出处。