java---装饰者模式

最近再学习Servlet,发现书上提到了GenericServlet这个类运用了装饰者模式,不是很懂故找了下面资料详解:

装饰者模式

举个例子,例子注释很多很容易看懂

//一开始人穷只是普通的吃饭
class Person{
    public void eat(){
        System.out.println("吃饭");
    }
}
//后来人富裕了,吃饭前会先喝酒
class Superman{
    private Person p;//这就是装饰者

    public Superman(Person p){
        this.p = p;//装饰者一般在构造函数中初始化
    }
    public void eat(){
        System.out.println("喝酒");
        p.eat();//使用装饰者
        System.out.println("唱歌");
    }
}
public class test {
    public static void main(String[] args) {
        new Superman(new Person()).eat();
        /**输出 * 喝酒 吃饭 唱歌 */
    }
}

和继承的区别:
人穷的时候只会吃饭,后来富裕了会先喝酒,那么之前吃饭那个模块需要保留下来,做的方法可以继承,但是如果只是想保留一个小功能而使用继承的话,未免使得整个程序结构变的臃肿不堪,因此装饰者模式就为了解决这样的问题而诞生的.\

GenericServlet的装饰者模式

先看源代码

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    private static final long serialVersionUID = 1L;
    //这就是我们的装饰者
    private transient ServletConfig config;

    public GenericServlet() {
    }

    public void destroy() {
    }

    public String getInitParameter(String name) {
        return this.getServletConfig().getInitParameter(name);
    }

    public Enumeration<String> getInitParameterNames() {
        return this.getServletConfig().getInitParameterNames();
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public ServletContext getServletContext() {
    //这里使用装饰者的方法getServletContext()
        return this.getServletConfig().getServletContext();
    }

    public String getServletInfo() {
        return "";
    }

    public void init(ServletConfig config) throws ServletException {
        //这里给装饰者初始化
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }

    public void log(String msg) {
        this.getServletContext().log(this.getServletName() + ": " + msg);
    }

    public void log(String message, Throwable t) {
        this.getServletContext().log(this.getServletName() + ": " + message, t);
    }

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    public String getServletName() {
        //这里也是使用装饰者的方法
        return this.config.getServletName();
    }
}

这里的装饰者是ServletConfig,那么只要是实现这个接口的对象传递进来都可以使用其里面的方法.


另外感觉和js里面的一种面向对象写法很相似,主要是通过一个对象来承载需要传达下去的方法,可能是借鉴了装饰者模式吧, 纯属个人瞎扯,,,,
下面是js代码

/** * Created by nl101 on 2016/1/23. */
//创建父类
function Person(name,id){
    //创建一个对象来承载父类所有公有东西
    //也就是说_this承载的对象才会被传递给子类
    var _this = {};
    _this.name = name;
    //这样的是不会传递下去的
    this.id = id;
    //承载方法
    _this.say = function(){
        alert("Person");
    }
    //返回_this对象
    return _this;
}
//子类
function Student(){
    //获取person的_this对象,从而模仿继承
    var _this = Person("iwne",1);
    //保存父类的_this引用
    var superPerson = _this.say;
    //复写父类的方法
    _this.say = function(){
        //执行父类的say
        superPerson.call(_this);
      alert("Student");
    }
    return _this;
}
var s = new Student();
s.say();

你可能感兴趣的:(设计模式)