Java设计模式之模板模式-学习笔记4

  模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

      模板模式的关键是:子类可以置换掉父类的可变部分,但是子类却不可以改变模板方法所代表的顶级逻辑,每当定义一个新的子类时,不要按照控制流程的思路去想,而应当按照“责任”的思路去想。换言之,应当考虑哪些操作是必须置换掉的,哪些操作是可以置换掉的,以及哪些操作是不可以置换掉的。使用模板模式可以使这些责任变得清晰,下面给出一个追求女孩的模板。

Coding:

1、模板类

 

/**
 * Java设计模式之模板模式
 * 
 * 吖大哥提供了一个文明而向上的追女孩的步骤,具体怎么追怎么才能成功就看你们自己了,健康有效的模板如下
 * 
 * @author 吖大哥
 * @date Jun 3, 2014 9:25:42 AM
 */
public abstract class AbstractTemplet {

	/** 巧遇 */
	public abstract void across();

	/** 约会 */
	public abstract void appointment();

	/** 表白 */
	public void express() {
		System.out.println("喜欢你");
	}

	/** 追求 */
	public abstract boolean pursuit();

	/** 接吻 */
	public abstract boolean kissing();

	/** 上床 */
	public void sleep() {
		boolean flag1 = pursuit();
		boolean flag2 = kissing();
		// 吖大哥建议两步成功之后可以考虑上床
		if (flag1 && flag2) {
			System.out.println("你可以和她上床了…………………………………………");
		} else if (!flag2 || !flag1) {
			System.out.println("你追求或者接吻失败啦,你们不能上床…………………………………………");
		}
	}

	/** 追女孩 */
	public final void chasingGirls() {// 使用final关键字锁定子类只能按如下步骤来追女孩
		across();
		appointment();
		express();
		sleep();
	}
}

2、浪漫的追求者类

 

 

/**
 * 浪漫温馨的追求者
 * 
 * @author 吖大哥
 * @date Jun 3, 2014 10:08:18 AM
 */
public class RomanticGetGirl extends AbstractTemplet {

	@Override
	public void across() {
		System.out.println("无意间的邂逅");
	}

	@Override
	public void appointment() {
		System.out.println("浪漫的约会");
	}

	@Override
	public boolean kissing() {
		System.out.println("深情的接吻");
		return true;
	}

	@Override
	public boolean pursuit() {
		System.out.println("缠绵的追求");
		return true;
	}

}

 3、狂野的追求者类

/**
 * 狂野的追求者
 * 
 * @author 吖大哥
 * @date Jun 3, 2014 10:08:42 AM
 */
public class CrazyGetGirlImpl extends AbstractTemplet {

	@Override
	public void across() {
		System.out.println("疯狂的偶遇");
	}

	/** 表白 */
	public void express() {
		System.out.println("我他妈的贱B嗖嗖的喜欢上你了");
	}

	@Override
	public void appointment() {
		System.out.println("疯狂的找人家约会");
	}

	@Override
	public boolean kissing() {
		return false;
	}

	@Override
	public boolean pursuit() {
		return false;
	}

	public void sleep() {
		System.out.println("咱们直接上床吧………………………………");
	}

}

 4、客户端测试

 

public class Client{

	public static void main(String[] args) {
		AbstractTemplet at1 = new RomanticGetGirl();
		at1.chasingGirls();
		System.out.println("================================");
		AbstractTemplet at2 = new CrazyGetGirlImpl();
		at2.chasingGirls();
	}
}

  5、测试结果:

 

无意间的邂逅
浪漫的约会
喜欢你
缠绵的追求
深情的接吻
你可以和她上床了…………………………………………
================================
疯狂的偶遇
疯狂的找人家约会
我他妈的贱B嗖嗖的喜欢上你了
咱们直接上床吧………………………………

 

 

 

模板方法模式在Servlet中的应用

  使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类。HttpService类提供了一个service()方法,这个方法调用七个do方法中的一个或几个,完成对客户端调用的响应。这些do方法需要由HttpServlet的具体子类提供,因此这是典型的模板方法模式。下面是service()方法的源代码

复制代码
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);        
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }
复制代码

 

  当然,这个service()方法也可以被子类置换掉。

  下面给出一个简单的Servlet例子:

    

  从上面的类图可以看出,TestServlet类是HttpServlet类的子类,并且置换掉了父类的两个方法:doGet()和doPost()。

 

复制代码
public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        System.out.println("using the GET method");

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            
        System.out.println("using the POST method");
    }

}
复制代码

 

  从上面的例子可以看出这是一个典型的模板方法模式。

  HttpServlet担任抽象模板角色

    模板方法:由service()方法担任。

    基本方法:由doPost()、doGet()等方法担任。

  TestServlet担任具体模板角色

    TestServlet置换掉了父类HttpServlet中七个基本方法中的其中两个,分别是doGet()和doPost()。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值