[toc]
Archetype
Archetype设计模式的目的是将业务处理逻辑和具体实现分离,所以至少需要两个参与者:Decorator和Delegate,它们都实现同一个接口,Decorator负责处理业务逻辑,而Delegate负责具体的实现,在Decorator的通用业务逻辑处理过程中,会把具体实现委派给Delegate。
假设系统中有一个记录各种事件的接口:
EventRecorder.java
1 2 3 4
| public interface EventRecorder { public void record(String event); }
|
引入两个抽象类来达到处理逻辑和具体实现分离的目的:
EventRecorderDelegate.java
1 2 3
| public abstract class EventRecorderDelegate implements EventRecorder {
}
|
EventRecorderDecorator.java
1 2 3 4 5 6 7
| public abstract class EventRecorderDecorator implements EventRecorder { protected EventRecorderDelegate delegate;
public void setDelegate(EventRecorderDelegate delegate) { this.delegate = delegate; } }
|
下面是两个简单的逻辑处理(Decorator)类:
ComplicateEventRecorder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ComplicateEventRecorder extends EventRecorderDecorator{ public void record(String event){ event = System.currentTimeMillis() + event; event = event+System.getenv(); delegate.record(event); } }
|
SimpleEventRecorder.java
1 2 3 4 5 6 7 8 9
| public class SimpleEventRecorder extends EventRecorderDecorator {
public void record(String event) { event = System.currentTimeMillis() + event; delegate.record(event); } }
|
最后一步都交给了EventRecorderDelegate对象,这一步就是之前所说的“具体实现”:
1 2 3 4 5
| public class RecordEventToDatabase extends EventRecorderDelegate { public void record(String event) { } }
|
1 2 3 4 5
| public class RecordEventToFile extends EventRecorderDelegate { public void record(String event) { } }
|
下面是一个生成事件记录对象的工厂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class EventRecorderFactory { public static EventRecorder create(int type, int flag) { EventRecorderDelegate delegate = null; EventRecorderDecorator decorator = null;
if (type == 0) decorator = new SimpleEventRecorder(); if (type == 1) decorator = new ComplicateEventRecorder();
if (flag == 0) delegate = new RecordEventToDatabase(); if (flag == 1) delegate = new RecordEventToFile(); decorator.setDelegate(delegate); return decorator; } }
|
从举的例子中可以看到,有2种业务处理逻辑,有2个具体实现,它们组成了4种事件记录方式。
Specification
在一个较为复杂的业务流程中,某些条件的满足与否决定了业务逻辑的走向,可以把这些条件抽离出来,使得任意个条件以某种关系进行组合,从而灵活地对业务逻辑进行定制。另外,在查询、过滤等应用场合中,也可以预定义多个条件,使用这些条件的组合来处理查询逻辑,而不是使用逻辑判断语句来处理,那样只会让代码变得复杂。
在Specification设计模式中,一个条件就是一个specification,多个specification通过串联的方式以某种逻辑关系形成一个组合式的specification。首先看一下整体的UML图:

下面是Specification接口的声明:
1 2 3 4 5 6 7 8 9 10 11
| public interface Specification {
boolean isSatisfiedBy(Object params);
Specification and(Specification other);
Specification or(Specification other);
Specification not();
}
|
它定义了各个条件间可用的关系:与、或、非,这三个关系所对应方法的返回值都是Specification自身,目的是为了实现 Specification之间的串联(chaining),从而形成一个关系表达式。isSatisfiedBy就是判定方法, 参数是一个Object,支持任意类型。
下面来看CompositSpecification的声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public abstract class CompositeSpecification implements Specification {
@Override public Specification and(Specification other) { return new AndSpecification(this, other); }
@Override public Specification not() { return new NotSpecification(this); }
@Override public Specification or(Specification other) { return new OrSpecification(this, other); } public abstract boolean isSatisfiedBy(Object params); }
|
它实现了Specification接口的关系判定方法,而isSatisfiedBy则仍是抽象方法,需要派生类来具体实现。下面是三个分别实现了与、或、非关系判定的派生类的声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class AndSpecification extends CompositeSpecification {
private final Specification b; private final Specification a;
public AndSpecification(Specification a, Specification b) { this.a = a; this.b = b; }
@Override public boolean isSatisfiedBy(Object params) { return a.isSatisfiedBy(params) && b.isSatisfiedBy(params); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class NotSpecification extends CompositeSpecification {
private final Specification a;
public NotSpecification(Specification a) { this.a = a; }
@Override public boolean isSatisfiedBy(Object params) { return !a.isSatisfiedBy(params); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class OrSpecification extends CompositeSpecification {
private final Specification b; private final Specification a;
public OrSpecification(Specification a, Specification b) { this.a = a; this.b = b; }
@Override public boolean isSatisfiedBy(Object params) { return a.isSatisfiedBy(params) || b.isSatisfiedBy(params); } }
|
这些类就构成了Specification模式的核心部分,下面来看一个例子:
先定义一个男人:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Men { public String name; public boolean married; public int cars; public int houses;
public Men(String name, int cars, int houses, boolean married) { this.name = name; this.cars = cars; this.houses = houses; this.married = married; } }
|
然后定义选男人的几个条件:
1 2 3 4 5 6 7 8
| public class HasCarsSpecification extends CompositeSpecification {
@Override public boolean isSatisfiedBy(Object params) { Men m = (Men)params; return m.cars > 0; } }
|
1 2 3 4 5 6 7 8 9
| public class HasHousesSpecification extends CompositeSpecification {
@Override public boolean isSatisfiedBy(Object params) { Men m = (Men) params; return m.houses > 0; }
}
|
1 2 3 4 5 6 7 8 9
| public class MarriedSpecification extends CompositeSpecification {
@Override public boolean isSatisfiedBy(Object params) { Men m = (Men) params; return m.married; } }
|
好,下面有位女嘉宾开始选它心目中的男人了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class Main {
public static void main(String[] args) {
Men[] candidates = { new Men("李精英", 1, 1, false), new Men("王老五", 5, 3, true), new Men("赵白领", 0, 1, false), new Men("West_Link", 0, 0, false) };
HasHousesSpecification hasHouse = new HasHousesSpecification(); HasCarsSpecification hasCar = new HasCarsSpecification(); MarriedSpecification married = new MarriedSpecification();
Specification spec = hasHouse.and(hasCar).and(married.not()); for (Men men : candidates) { if (spec.isSatisfiedBy(men)) System.out.println(men.name); }
}
}
|
从Specification spec = hasHouse.and(hasCar).and(married.not())这行代码可以看出这位女嘉宾选择了有车并且有房的未婚男子,所以打印结果为:李精英。
Publish-Subscribe
很多项目中都有消息分发或者事件通知机制,尤其是模块化程度高的项目。例如在办公自动化系统 中,有些子系统对于新建用户这一事件很感兴趣,权限模块希望为这个新用户设置默认的权限,报表模块希望重新生成当月的报表,诸如此类的代码都写到新建用户 的业务逻辑后面,会加大耦合度,可维护性降低,并且对于每个模块都是一个独立工程的情况,这种方式更是不可取。
对于简单的情形,观察者模式就适用了,如果系统中有很多地方都需要收发消息,那么它就不适用了,否则会造成类数量的膨胀,增加类的复杂性,这时候就需要一种更集中的机制,Publish- Subscribe机制是个不错的选择,它的耦合性低,各个参与者之间毫无关联。每 一个消息都有一个唯一标识,一般都用字符串来描述,比如用户管理模块中新添加了一个用户,于是它发送了一个消息:/UserManagment/User/Add,消息的其他信息可以放置到一个Map中。下面是一个最简单的消息订阅接口:
1 2 3 4 5
| public interface MessageSubscriber {
public void onRecived(String message, Map params); }
|
当订阅的消息发出后,MessageSubscriber的onRecived方法就会被调 用,消息相关的特定信息存储在参数params中。 一个消息可以被多个对象订阅,一个对象可以订阅多个消息,所以onRecived的第一个参数是消息的名称,如果对象订阅了多个消息,可能需要根据消息类 型来进行具体的操作。
下面消息发送的实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class MessagePublisher { private static MessagePublisher singleton; private static Map<String, ArrayList<MessageSubscriber>> subscribers;
private MessagePublisher() { }
public static MessagePublisher instance() { if (singleton == null) singleton = new MessagePublisher(); return singleton; }
public void register(String message, MessageSubscriber subscriber) { if (subscriber == null) return; if (subscribers == null) subscribers = new LinkedHashMap<String, ArrayList<MessageSubscriber>>(); ArrayList<MessageSubscriber> subscriberList = subscribers.get(message); if (subscriberList == null) { subscriberList = new ArrayList<MessageSubscriber>(); subscribers.put(message, subscriberList); } subscriberList.add(subscriber); }
public void publish(String message, Map params) { if (subscribers == null) return; ArrayList<MessageSubscriber> subscriberList = subscribers.get(message); if (subscriberList == null || subscriberList.isEmpty()) return; for (MessageSubscriber topicSubscriber : subscriberList) topicSubscriber.onRecived(message, params); } }
|
该类中主要包含两个方 法:register用来注册消息订阅者,publish用来发送消息。这样,对某个事件感兴趣的模块就可以通过MessagePublisher来订阅 这个相关的消息,而产生事件的模块就可以通过MessagePublisher将其发布出去。
测试示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package test.publishsubscribe;
import java.util.HashMap; import java.util.Map;
public class Test {
public static void main(String[] args) { MessagePublisher messagePublisher = MessagePublisher.instance(); messagePublisher.register("/User/Add", new ASubscriber()); messagePublisher.register("/User/Del", new BSubscriber()); Map<String, String> params = new HashMap(); params.put("id", "001"); params.put("name", "zero"); messagePublisher.publish("/User/Add", params); messagePublisher.publish("/User/Del", params); } }
class ASubscriber implements MessageSubscriber {
@Override public void onRecived(String message, Map params) { System.out.println("ASubscriber : message=" + message + ", content = " + params); }
}
class BSubscriber implements MessageSubscriber {
@Override public void onRecived(String message, Map params) { System.out.println("BSubscriber : message=" + message + ", content = " + params); }
}
|
ASubscriber订阅“/User/Add”的内容,BSubscriber订阅“/User/Del”的内容。当messagePublisher发布时消息时,订阅该消息的将会执行onRecived()方法。
转载自:
http://blog.csdn.net/m13666368773/article/details/7472126
http://blog.csdn.net/m13666368773/article/details/7472140
http://blog.csdn.net/m13666368773/article/details/7472157