Archetype&Specification&Publish-Subscribe

转载自:http://blog.youkuaiyun.com/m13666368773/article/details/7472126
             http://blog.youkuaiyun.com/m13666368773/article/details/7472140

             http://blog.youkuaiyun.com/m13666368773/article/details/7472157


Archetype

      Archetype设计模式的目的是将业务处理逻辑和具体实现分离,所以至少需要两个参与者:Decorator和Delegate,它们都实现同一个接口,Decorator负责处理业务逻辑,而Delegate负责具体的实现,在Decorator的通用业务逻辑处理过程中,会把具体实现委派给Delegate。
假设系统中有一个记录各种事件的接口:
EventRecorder.java
public interface EventRecorder {
	// 记录事件的内容
	public void record(String event);
}
引入两个抽象类来达到处理逻辑和具体实现分离的目的:
EventRecorderDelegate.java
public abstract class EventRecorderDelegate implements EventRecorder {
}
EventRecorderDecorator.java
public abstract  class EventRecorderDecorator implements EventRecorder {
	protected EventRecorderDelegate delegate;

	public void setDelegate(EventRecorderDelegate delegate) {
		this.delegate = delegate;
	}
}
下面是两个简单的逻辑处理(Decorator)类:
ComplicateEventRecorder.java
public class ComplicateEventRecorder extends EventRecorderDecorator{
    
    public void record(String event){
        // 附加当前的日期到事件的内容中
        event = System.currentTimeMillis() + event;
        // 附加当前异常信息到事件的内容中
  
        // 附加当前的env
        event = event+System.getenv();
        
        // 记录事件的内容
        delegate.record(event);
    }
}
SimpleEventRecorder.java
public class SimpleEventRecorder extends EventRecorderDecorator {

	public void record(String event) {
		// 附加当前的日期到事件的内容中
		event = System.currentTimeMillis() + event;
		// 记录事件的内容
		delegate.record(event);
	}
}
最后一步都交给了EventRecorderDelegate对象,这一步就是之前所说的“具体实现”:
public class RecordEventToDatabase extends EventRecorderDelegate {
	public void record(String event) {
		// 将记录写入到数据库中
	}
}
public class RecordEventToFile extends EventRecorderDelegate {
	public void record(String event) {
		// 将记录写入到文件中
	}
}
下面是一个生成事件记录对象的工厂:
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接口的声明:
public interface Specification {

	boolean isSatisfiedBy(Object params);

	Specification and(Specification other);

	Specification or(Specification other);

	Specification not();

}
      它定义了各个条件间可用的关系:与、或、非,这三个关系所对应方法的返回值都是Specification自身,目的是为了实现 Specification之间的串联(chaining),从而形成一个关系表达式。isSatisfiedBy就是判定方法, 参数是一个Object,支持任意类型。
下面来看CompositSpecification的声明:
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则仍是抽象方法,需要派生类来具体实现。下面是三个分别实现了与、或、非关系判定的派生类的声明:
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);
	}
}
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);
	}

}
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模式的核心部分,下面来看一个例子:
先定义一个男人:
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;
	}
}
然后定义选男人的几个条件:
public class HasCarsSpecification extends CompositeSpecification {

    @Override
    public boolean isSatisfiedBy(Object params) {
          Men m = (Men)params;
          return m.cars > 0;
    }
}
public class HasHousesSpecification extends CompositeSpecification {

	@Override
	public boolean isSatisfiedBy(Object params) {
		Men m = (Men) params;
		return m.houses > 0;
	}

}
public class MarriedSpecification extends CompositeSpecification {

	@Override
	public boolean isSatisfiedBy(Object params) {
		Men m = (Men) params;
		return m.married;
	}
}
好,下面有位女嘉宾开始选心目中的男人了:
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		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机制是个不错的选择,它的耦合性低,各个参与者之间毫无关联。每 一个消息都有一个唯一标识,一般都用字符串来描述,比如用户管理模块中新添加了一个用户,于是它发送了一个消息:/User/Add,消息的其他信息可以放置到一个Map中。下面是一个最简单的消息订阅接口:
public interface MessageSubscriber {

	public void onRecived(String message, Map params);
	
}
      当订阅的消息发出后,MessageSubscriber的onRecived方法就会被调 用,消息相关的特定信息存储在参数params中。 一个消息可以被多个对象订阅,一个对象可以订阅多个消息,所以onRecived的第一个参数是消息的名称,如果对象订阅了多个消息,可能需要根据消息类 型来进行具体的操作。
下面消息发送的实现类:
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将其发布出去。
测试示例:
public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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) {
		// TODO Auto-generated method stub
		System.out.println("ASubscriber : message=" + message + ", content = "
				+ params);
	}

}

class BSubscriber implements MessageSubscriber {

	@Override
	public void onRecived(String message, Map params) {
		// TODO Auto-generated method stub
		System.out.println("BSubscriber : message=" + message + ", content = "
				+ params);
	}

}

      ASubscriber订阅“/User/Add”的内容,BSubscriber订阅“/User/Del”的内容。当messagePublisher发布时消息时,订阅该消息的将会执行onRecived()方法。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值