本文共 5365 字,大约阅读时间需要 17 分钟。
基本含义不再详述
分类:一般根据目的划分为三类:创建型模式、结构型模式、行为型模式几大原则:
应用场景:
实现代码:
public class Singleton { private static Singleton singleton=null; //避免在外部被实例化 private Singleton(){ }; public static synchronized Singleton getSingleton(){ if(singleton==null){ singleton=new Singleton(); }else{ System.out.println("已经被实例化了"); } return singleton; }}
含义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。
应用场景:
分类:
实现代码:
public class ProtoType implements Cloneable{ private int id; private String name; private AccProtoType accProtoType; public ProtoType(){ }; public Object clone() throws CloneNotSupportedException { return (ProtoType)super.clone(); }}
测试代码:
//原型模式测试 ProtoType p1=new ProtoType(); p1.setId(1); p1.setName("我是本体"); AccProtoType accProtoType=new AccProtoType(11); p1.setAccProtoType(accProtoType); ProtoType p2= (ProtoType) p1.clone(); System.out.println(p1.getId()+p1.getName()+p1.getAccProtoType().id); System.out.println(p2.getId()+p2.getName()+p2.getAccProtoType().id); System.out.println(p1==p2); p1.setId(2); p1.setName("我是copy"); accProtoType.id=22; System.out.println(p1.getId()+p1.getName()+p1.getAccProtoType().id); System.out.println(p2.getId()+p2.getName()+p2.getAccProtoType().id);
结果:
解释一下最后两行的后两个字段,因为浅复制只复制了引用,p1在修改name属性时,由于name为String类型,无法修改,所以虚拟机只能在内存中新建一个String,值为“我是copy”,并将该引用指向p1,所以p2的引用还是原引用,值也就仍然时“我是本体”,而修改accProtoType的id属性时,并没有改变引用,所以p1和p2中的accProtoType仍然是同一个对象,自然属性值也相同。深克隆:AccProtoType中也实现clone()方法。
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
优点:解耦合
缺点:依赖关系并没有完全解除,可能出现循环引用。当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。三要素:事件、事件源、监听者
示例程序:
BellEvent类:import java.util.EventObject;public class BellEvent extends EventObject { public BellEvent(EventSource eventSource) { super(eventSource); }}
ExamEvent类:
import java.util.EventObject;public class ExamEvent extends EventObject { public ExamEvent(EventSource eventSource){ super(eventSource); }}
EventSource类:
import java.util.*;public class EventSource { private Map> listerMap=new HashMap >(); public void addListener(EventObject eventObject,EventLister lister){ if(listerMap.get(eventObject.getClass().getSimpleName())==null){ HashSet set=new HashSet (); set.add(lister); listerMap.put(eventObject.getClass().getSimpleName(), set); }else { listerMap.get(eventObject.getClass().getSimpleName()).add(lister); } } public void removeListener(BellEvent event,EventLister lister){ listerMap.get(event.getClass().getSimpleName()).remove(lister); } public void start(EventObject eventObject){ System.out.println("开始通知"+eventObject.getClass().getSimpleName()+"事件的监听者"); notify(eventObject); } private void notify(EventObject eventObject){ Iterator iterator=listerMap.get(eventObject.getClass().getSimpleName()).iterator(); while (iterator.hasNext()){ iterator.next().handle(); } }}
Listener接口:
public interface EventListener { public void handle();}
TeacherEventListener类:
public class TeacherEventListener implements EventLister { @Override public void handle() { System.out.println("老师去上课了"); }}
StudentEventListener类:
public class StudentEventListener implements EventLister { @Override public void handle() { System.out.println("学生开始考试"); }}
测试类:
public class main { public static void main(String[] args) { EventSource eventSource=new EventSource(); BellEvent bellEvent=new BellEvent(eventSource); ExamEvent examEvent=new ExamEvent(eventSource); eventSource.addListener(bellEvent,new TeacherEventListener()); eventSource.addListener(examEvent,new StudentEventListener()); eventSource.start(bellEvent); eventSource.start(examEvent); }}
效果:
开始通知BellEvent事件的监听者老师去上课了开始通知ExamEvent事件的监听者学生开始考试
转载地址:http://trzwi.baihongyu.com/