Decorator模式


一、应用场景:

假设我们已经存在这样的一个程序:

1).该程序从一个列表中拿出所有的用户名单,然后逐个向用户发送一句信息。
2).现在我们又增加了一个新的需求:在发送之前检查一下该用户是否存在于黑名单中,如果是的话则不发送给该用户。
3).是否进行检查则动态根据用户的当时需要来决定。

二、需求分析:

从上面的情况分析,如果我们采用继承的方式,重新编写一个带有过滤功能的发送程序,则必须完全改写原有的发送方法,插入过滤的过程。如果我们采用Decorator模式的话,可以怎么做呢?

首先分析一下需求的公共部分,相同的部分都是发送信息,不管是否需要进行过滤。也就是说只有发送的方法拿到数据,它就不管三七二十一发出去了,所以这个功能应该可以被抽象成一个接口。

接下来我们来看一下,既然新的功能只是在旧的功能之前插入了“过滤”这一简单的过程,原有的功能保持不变,所以我们完全可以把旧的功能委托给老的程序来进行。既然是委托了那么必然在新的类里面要含有一个旧的对象的引用。

最后如何实现“动态插入过滤功能”呢?我们看一下前面的接口,如果我们实现了接口,那么在其实现方法中就可以重写原来的方法,增加过滤功能了。

三、系统设计:

我们来看一下下面这张图,明确一下各个对象之间的联系





在这张图中我们看到:我们抽象出了一个接口:ISendMessage接口,原有的SendMessageImpl类和新增的SendMessageDecorator类都实现了该接口。Decorator类有一个对SendMessageImpl的委托。

四、详细代码:

·ISendMessage:

package  org.pattern.decorator;

public   interface  ISendMessage  {

    
public void send();
}


·SendMessageImpl:

package  org.pattern.decorator;

import  java.util.ArrayList;
import  java.util.Iterator;
import  java.util.List;

public   class  SendMessageImpl  implements  ISendMessage  {

    List
<String> users = new ArrayList<String>();
    
    
public void setUsers(List<String> users) {
        
this.users = users;
    }


    
public List<String> getUsers() {
        
return users;
    }


    
// Implement
    public void send() {
        
for (Iterator it = users.iterator(); it.hasNext();) {
            String user 
= (String) it.next();
            System.out.println(
"This is for your message : " + user);
        }

    }


}


·SendMessageDecorator:

package  org.pattern.decorator;

import  java.util.ArrayList;
import  java.util.Iterator;
import  java.util.List;

public   class  SendMessageDecorator  implements  ISendMessage  {

    
private ISendMessage isendMessage;

    
private boolean filter = false;

    
private List<String> blackUsers = new ArrayList<String>();
    
    
// Constructor method
    public SendMessageDecorator(ISendMessage isendMessage){
        
this.isendMessage = isendMessage;
    }


    
// Constructor method with filter flag and black user list
    public SendMessageDecorator(ISendMessage isendMessage, boolean filter,
            List
<String> blackUsers) {
        this.isendMessage = isendMessage;
        this.filter = filter;
        
this.blackUsers = blackUsers;
    }


    
// Decorator operation: dynamicly add filter logic if needed
    public void send() {
        
if (!filter) {
            isendMessage.send();
        }
 else {
            filter(blackUsers);
            isendMessage.send();
        }

    }


    
private void filter(List<String> blackUsers) {
        
// Return if black users list is null
        if (blackUsers == null{
            
return;
        }

        
// Remove all users which mattch the black list
        List users = ((SendMessageImpl) isendMessage).getUsers();
        List
<String> newList = new ArrayList<String>();
        
for (Iterator it = users.iterator(); it.hasNext();) {
            String user 
= (String) it.next();
            
if (!blackUsers.contains(user)) {
                newList.add(user);    
            }

        }

        ((SendMessageImpl)isendMessage).setUsers(newList);
    }


}


·DecoratorTest:

package  org.pattern.decorator;

import  java.util.ArrayList;
import  java.util.List;

public   class  DecoratorTest  {

    
public static void main(String args[]) {
        DecoratorTest dt 
= new DecoratorTest();
        dt.test(args[
0]);    
    }


    
private void test(String arg) {
        
// Create users
        List<String> users = new ArrayList<String>();
        users.add(
"Paul");
        users.add(
"Bob");
        users.add(
"Tom");
        users.add(
"Jim");
        
// Set users
        SendMessageImpl sender = new SendMessageImpl();
        sender.setUsers(users);
        
// Create Decorator
        if (arg == null || arg.trim().length() == 0 || arg.equalsIgnoreCase("no")) {
            ISendMessage decorator 
= new SendMessageDecorator(sender);
            decorator.send();
        }
 else {
            List
<String> blackUsers = new ArrayList<String>();
            blackUsers.add(
"Tom");
            blackUsers.add(
"Jim");
           ISendMessage decorator = new SendMessageDecorator(sender, true,
                    blackUsers);
            decorator.send();

        }

    }


}


五、Decorator模式的特点:

A. Decorator类实现了接口(抽象)
B. Decorator类中包含一个接口类型的属性,并通过适当的方式被实例化
C. Decorator类中实现接口的抽象方法,委托父类属性完成基本功能,同时加入额外功能或改变工作流


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值