|
享元模式
享元模式采用一个共享来避免大量拥有相同内容对象的开销;享元模式以共享的方式高效地支持大量的细粒度对象
像String型,就是享元模式的;
代理模式
为其他对象提供一种代理以控制对这个对象的访问
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
静态代理
eg:栗子来自《Java与模式》
/**
* 抽象角色
*/
public abstract class Subject{
public abstract void request();
}
/**
* 真实的角色
*/
public class RealSubjectextends Subject{
@Override
public void request(){
// TODO Auto-generated method stub
}
}
/**
* 静态代理,对具体真实对象直接引用
* 代理角色,代理角色需要有对真实角色的引用,
* 代理做真实角色想做的事情
*/
public class ProxySubjectextends Subject{
private RealSubject realSubject = null;
/**
* 除了代理真实角色做该做的事情,代理角色也可以提供附加操作,
* 如:preRequest()和postRequest()
*/
@Override
public void request(){
preRequest(); //真实角色操作前的附加操作
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();
postRequest(); //真实角色操作后的附加操作
}
/**
* 真实角色操作前的附加操作
*/
private void postRequest(){
// TODO Auto-generated method stub
}
/**
* 真实角色操作后的附加操作
*/
private void preRequest(){
// TODO Auto-generated method stub
}
}
/**
* 客户端调用
*/
public class Main{
public static void main(String[] args){
Subject subject = new ProxySubject();
subject.request(); //代理者代替真实者做事情
}
}
动态代理
Java动态代理类位于Java.lang.reflect包下
ge:
package dynamicproxy;
/**
* 抽象角色
* 这里应改为接口
*/
public interface Subject{
void request();
}
/**
* 真实的角色
* 实现接口
*/
public class RealSubjectimplements Subject{
@Override
public void request(){
// TODO Auto-generated method stub
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理, 它是在运行时生成的class,在生成它时你必须提供一组interface给它, 然后该class就宣称它实现了这些interface。
* 你当然可以把该class的实例当作这些interface中的任何一个来用。 当然啦,这个Dynamic
* Proxy其实就是一个Proxy,它不会替你作实质性的工作, 在生成它的实例时你必须提供一个handler,由它接管实际的工作。
*/
public class DynamicSubjectimplements InvocationHandler{
private Object sub; // 真实对象的引用
public DynamicSubject(Object sub){
this.sub = sub;
}
@Override
publicObjectinvoke(Object proxy, Method method, Object[] args)throwsThrowable{
System.out.println("before calling " + method);
method.invoke(sub,args);
System.out.println("after calling " + method);
return null;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Main{
public static void main(String[] args)throwsThrowable{
RealSubject rs = new RealSubject();
InvocationHandler handler = new DynamicSubject(rs);
Class cls = rs.getClass();
//以下是分解步骤
/*
Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces());
Constructor ct = c.getConstructor(new Class[]{InvocationHandler.class});
Subject subject =(Subject) ct.newInstance(new Object[]{handler});
*/
//以下是一次性生成
Subject subject = (Subject)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(), handler);
subject.request();
}
}
行为型模式
模版方法模式
定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤
模版方法定义了一个算法的步骤,并且允许子类为一个或多个步骤提供实现
eg:栗子来自: http://blog.csdn.net/lmj623565791/article/details/26276093
博主的WorkDay栗子;
public abstract class Worker
{
protected String name;
public Worker(String name)
{
this.name = name;
}
/**
* 记录一天的工作
*/
public final void workOneDay()
{
System.out.println("-----------------work start ---------------");
enterCompany();
computerOn();
work();
computerOff();
exitCompany();
System.out.println("-----------------work end ---------------");
}
/**
* 工作
*/
public abstract void work();
/**
* 关闭电脑
*/
private void computerOff()
{
System.out.println(name + "关闭电脑");
}
/**
* 打开电脑
*/
private void computerOn()
{
System.out.println(name + "打开电脑");
}
/**
* 进入公司
*/
public void enterCompany()
{
System.out.println(name + "进入公司");
}
/**
* 离开公司
*/
public void exitCompany()
{
System.out.println(name + "离开公司");
}
}
/ *
* codeMokey
/ *
public class ITWorkerextends Worker
{
public ITWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "写程序-测bug-fix bug");
}
}
public class HRWorkerextends Worker
{
public HRWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "看简历-打电话-接电话");
}
}
public class Test
{
public static void main(String[] args)
{
Worker it1 = new ITWorker("鸿洋");
it1.workOneDay();
Worker it2 = new ITWorker("老张");
it2.workOneDay();
Worker hr = new HRWorker("迪迪");
hr.workOneDay();
Worker qa = new QAWorker("老李");
qa.workOneDay();
Worker pm = new ManagerWorker("坑货");
pm.workOneDay();
}
}
命令模式
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象
将请求封装成对象,将动作请求者和动作执行者解耦
eg:栗子来自: http://blog.csdn.net/lmj623565791/article/details/24602057
/**
* 门
* @author zhy
*
*/
public class Door
{
public void open()
{
System.out.println("打开门");
}
public void close()
{
System.out.println("关闭门");
}
}
/**
* 电灯
* @author zhy
*
*/
public class Light
{
public void on()
{
System.out.println("打开电灯");
}
public void off()
{
System.out.println("关闭电灯");
}
}
/**
* 电脑
* @author zhy
*
*/
public class Computer
{
public void on()
{
System.out.println("打开电脑");
}
public void off()
{
System.out.println("关闭电脑");
}
}
/**
* 封装命令
*
*/
public interface Command
{
public void execute();
}
/**
* 关闭电灯的命令
* @author zhy
*
*/
public class LightOffCommondimplements Command
{
private Light light ;
public LightOffCommond(Light light)
{
this.light = light;
}
@Override
public void execute()
{
light.off();
}
}
/**
* 打开电灯的命令
* @author zhy
*
*/
public class LightOnCommondimplements Command
{
private Light light ;
public LightOnCommond(Light light)
{
this.light = light;
}
@Override
public void execute()
{
light.on();
}
}
/**
* 开电脑的命令
* @author zhy
*
*/
public class ComputerOnCommondimplements Command
{
private Computer computer ;
public ComputerOnCommond( Computer computer)
{
this.computer = computer;
}
@Override
public void execute()
{
computer.on();
}
}
/**
* 关电脑的命令
* @author zhy
*
*/
public class ComputerOffCommondimplements Command
{
private Computer computer ;
public ComputerOffCommond( Computer computer)
{
this.computer = computer;
}
@Override
public void execute()
{
computer.off();
}
}
/**
* 控制器面板,一共有9个按钮
*
* @author zhy
*
*/
public class ControlPanel
{
private static final int CONTROL_SIZE = 9;
private Command[] commands;
public ControlPanel()
{
commands = new Command[CONTROL_SIZE];
/**
* 初始化所有按钮指向空对象
*/
for (int i = 0; i < CONTROL_SIZE; i++)
{
commands[i] = new NoCommand();
}
}
/**
* 设置每个按钮对应的命令
* @param index
* @param command
*/
public void setCommand(intindex, Command command)
{
commands[index] = command;
}
/**
* 模拟点击按钮
* @param index
*/
public void keyPressed(intindex)
{
commands[index].execute();
}
}
public class NoCommandimplements Command
{
@Override
public void execute()
{
}
}
public class Test
{
public static void main(String[] args)
{
/**
* 三个家电
*/
Light light = new Light();
Door door = new Door();
Computer computer = new Computer();
/**
* 一个控制器,假设是我们的app主界面
*/
ControlPanel controlPanel = new ControlPanel();
// 为每个按钮设置功能
controlPanel.setCommand(0, new LightOnCommond(light));
controlPanel.setCommand(1, new LightOffCommond(light));
controlPanel.setCommand(2, new ComputerOnCommond(computer));
controlPanel.setCommand(3, new ComputerOffCommond(computer));
controlPanel.setCommand(4, new DoorOnCommond(door));
controlPanel.setCommand(5, new DoorOffCommond(door));
// 模拟点击
controlPanel.keyPressed(0);
controlPanel.keyPressed(2);
controlPanel.keyPressed(3);
controlPanel.keyPressed(4);
controlPanel.keyPressed(5);
controlPanel.keyPressed(8);// 这个没有指定,但是不会出任何问题,我们的NoCommand的功劳
}
}
迭代器模式
提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节
结构:
抽象容器:一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
具体容器:就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
抽象迭代器:定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove();
迭代器实现:实现迭代器接口中定义的方法,完成集合的迭代。
eg:栗子来自: http://blog.csdn.net/zhengzhb/article/details/7610745
interface Iterator{
publicObjectnext();
public boolean hasNext();
}
class ConcreteIteratorimplements Iterator{
private List list = new ArrayList();
private int cursor =0;
public ConcreteIterator(List list){
this.list = list;
}
public boolean hasNext(){
if(cursor==list.size()){
return false;
}
return true;
}
publicObjectnext(){
Object obj = null;
if(this.hasNext()){
obj = this.list.get(cursor++);
}
return obj;
}
}
interface Aggregate{
public void add(Object obj);
public void remove(Object obj);
publicIteratoriterator();
}
class ConcreteAggregateimplements Aggregate{
private List list = new ArrayList();
public void add(Object obj){
list.add(obj);
}
publicIteratoriterator(){
return new ConcreteIterator(list);
}
public void remove(Object obj){
list.remove(obj);
}
}
public class Client{
public static void main(String[] args){
Aggregate ag = new ConcreteAggregate();
ag.add("小明");
ag.add("小红");
ag.add("小刚");
Iterator it = ag.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
}
}
观察者模式
定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新
eg:栗子来自: http://blog.csdn.net/lmj623565791/article/details/24179699
/**
* 主题接口,所有的主题必须实现此接口
*
* @author zhy
*
*/
public interface Subject
{
/**
* 注册一个观察着
*
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除一个观察者
*
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知所有的观察着
*/
public void notifyObservers();
}
/**
* @author zhy 所有的观察者需要实现此接口
*/
public interface Observer
{
public void update(String msg);
}
import java.util.ArrayList;
import java.util.List;
public class ObjectFor3Dimplements Subject
{
private List<Observer> observers = new ArrayList<Observer>();
/**
* 3D彩票的号码
*/
private String msg;
@Override
public void registerObserver(Observer observer)
{
observers.add(observer);
}
@Override
public void removeObserver(Observer observer)
{
int index = observers.indexOf(observer);
if (index >= 0)
{
observers.remove(index);
}
}
@Override
public void notifyObservers()
{
for (Observer observer : observers)
{
observer.update(msg);
}
}
/**
* 主题更新消息
*
* @param msg
*/
public void setMsg(String msg)
{
this.msg = msg;
notifyObservers();
}
}
//User:
public class Observer1implements Observer
{
private Subject subject;
public Observer1(Subject subject)
{
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(String msg)
{
System.out.println("observer1 得到 3D 号码 -->" + msg + ", 我要记下来。");
}
}
public class Test
{
public static void main(String[] args)
{
//模拟一个3D的服务号
ObjectFor3D subjectFor3d = new ObjectFor3D();
//客户1
Observer observer1 = new Observer1(subjectFor3d);
Observer observer2 = new Observer2(subjectFor3d);
subjectFor3d.setMsg("20140420的3D号码是:127" );
subjectFor3d.setMsg("20140421的3D号码是:333" );
}
}
中介者模式
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互
角色:
抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。
同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如有六个同事类对象,假如对象1发生变化,会有4个对象受到影响。如果对象2发生变化,那么会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
如果引入中介者模式,那么同事类之间的关系将变为星型结构,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
eg:栗子来自: http://blog.csdn.net/jason0539/article/details/45216585
bstract class AbstractColleague{
protected int number;
public int getNumber(){
return number;
}
public void setNumber(intnumber){
this.number = number;
}
//抽象方法,修改数字时同时修改关联对象
public abstract void setNumber(intnumber, AbstractColleague coll);
}
class ColleagueAextends AbstractColleague{
public void setNumber(intnumber, AbstractColleague coll){
this.number = number;
coll.setNumber(number*100);
}
}
class ColleagueBextends AbstractColleague{
public void setNumber(intnumber, AbstractColleague coll){
this.number = number;
coll.setNumber(number/100);
}
}
//*********************************************************************
abstract class AbstractMediator{
protected AbstractColleague A;
protected AbstractColleague B;
public AbstractMediator(AbstractColleague a, AbstractColleague b){
A = a;
B = b;
}
public abstract void AaffectB();
public abstract void BaffectA();
}
class Mediatorextends AbstractMediator{
public Mediator(AbstractColleague a, AbstractColleague b){
super(a, b);
}
//处理A对B的影响
public void AaffectB(){
int number = A.getNumber();
B.setNumber(number*100);
}
//处理B对A的影响
public void BaffectA(){
int number = B.getNumber();
A.setNumber(number/100);
}
}
//**********************************************************************
public class Client{
public static void main(String[] args){
AbstractColleague collA = new ColleagueA();
AbstractColleague collB = new ColleagueB();
System.out.println("==========设置A影响B==========");
collA.setNumber(1288, collB);
System.out.println("collA的number值:"+collA.getNumber());
System.out.println("collB的number值:"+collB.getNumber());
System.out.println("==========设置B影响A==========");
collB.setNumber(87635, collA);
System.out.println("collB的number值:"+collB.getNumber());
System.out.println("collA的number值:"+collA.getNumber());
}
}
中介模式能够避免类与类之间的过度耦合;
它将类与类之间的关系转换为星型结构;
备忘录模式
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。
http://www.cnblogs.com/java-my-life/archive/2012/06/06/2534942.html
解释器模式
给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
http://www.cnblogs.com/java-my-life/archive/2012/06/19/2552617.html
状态模式
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类
当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。
eg:栗子来自: http://blog.csdn.net/lmj623565791/article/details/26350617
/**
* 自动售货机
*
* @author zhy
*
*/
public class VendingMachine
{
/**
* 已投币
*/
private final static int HAS_MONEY = 0;
/**
* 未投币
*/
private final static int NO_MONEY = 1;
/**
* 售出商品
*/
private final static int SOLD = 2;
/**
* 商品售罄
*/
private final static int SOLD_OUT = 3;
private int currentStatus = NO_MONEY;
/**
* 商品数量
*/
private int count = 0;
public VendingMachine(intcount)
{
this.count = count;
if (count > 0)
{
currentStatus = NO_MONEY;
}
}
/**
* 投入硬币,任何状态用户都可能投币
*/
public void insertMoney()
{
switch (currentStatus)
{
case NO_MONEY:
currentStatus = HAS_MONEY;
System.out.println("成功投入硬币");
break;
case HAS_MONEY:
System.out.println("已经有硬币,无需投币");
break;
case SOLD:
System.out.println("请稍等...");
break;
case SOLD_OUT:
System.out.println("商品已经售罄,请勿投币");
break;
}
}
/**
* 退币,任何状态用户都可能退币
*/
public void backMoney()
{
switch (currentStatus)
{
case NO_MONEY:
System.out.println("您未投入硬币");
break;
case HAS_MONEY:
currentStatus = NO_MONEY;
System.out.println("退币成功");
break;
case SOLD:
System.out.println("您已经买了糖果...");
break;
case SOLD_OUT:
System.out.println("您未投币...");
break;
}
}
/**
* 转动手柄购买,任何状态用户都可能转动手柄
*/
public void turnCrank()
{
switch (currentStatus)
{
case NO_MONEY:
System.out.println("请先投入硬币");
break;
case HAS_MONEY:
System.out.println("正在出商品....");
currentStatus = SOLD;
dispense();
break;
case SOLD:
System.out.println("连续转动也没用...");
break;
case SOLD_OUT:
System.out.println("商品已经售罄");
break;
}
}
/**
* 发放商品
*/
private void dispense()
{
switch (currentStatus)
{
case NO_MONEY:
case HAS_MONEY:
case SOLD_OUT:
throw new IllegalStateException("非法的状态...");
case SOLD:
count--;
System.out.println("发出商品...");
if (count == 0)
{
System.out.println("商品售罄");
currentStatus = SOLD_OUT;
} else
{
currentStatus = NO_MONEY;
}
break;
}
}
}
策略模式
定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户
(代码好长啊……懒得贴了)
传送门: http://blog.csdn.net/lmj623565791/article/details/24116745
职责链模式(责任链模式)
责任链模式,我记得Android的事件分发机制就是责任链模式的;
之前在学习分发机制的时候有过一些记录: Android自定义View——事件分发机制学习笔记
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
有一种比较简单的解释大概是酱紫的:领导给小组长安排工作,然后小组长再把工作分配给组员;如果组员做的了就揽下来,否则反馈给组长;若组长做的了就揽下来;
一种实现:
角色:
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
eg:栗子来自: http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
《Java与模式》
1.抽象处理者:
public abstract class Handler{
/**
* 持有后继的责任对象
*/
protected Handler successor;
/**
* 示意处理请求的方法,虽然这个示意方法是没有传入参数的
* 但实际是可以传入参数的,根据具体需要来选择是否传递参数
*/
public abstract void handleRequest();
/**
* 取值方法
*/
publicHandlergetSuccessor(){
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor){
this.successor = successor;
}
}
2.具体处理者
public class ConcreteHandlerextends Handler{
/**
* 处理方法,调用此方法处理请求
*/
@Override
public void handleRequest(){
/**
* 判断是否有后继的责任对象
* 如果有,就转发请求给后继的责任对象
* 如果没有,则处理请求
*/
if(getSuccessor() != null)
{
System.out.println("放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("处理请求");
}
}
}
3.Test:
public class Client{
public static void main(String[] args){
//组装责任链
Handler handler1 = new ConcreteHandler();
Handler handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
//提交请求
handler1.handleRequest();
}
}
原文出处://www.codercto.com/a/Y3RvMjkxNWN0bw==.html
程序猿的技术大观园:www.javathinker.net
|
|