7、缺省适配器模式

当前项目中的程序不使用缺省适配器模式,分析程序存在的缺点:

假设接口CommonIn有7个方法,当前程序中实现类A,B,C只需要使用CommonIn接口中的m1,m2,m3方法,让这些类直接实现这个接口,需要实现更多的方法,代码丑陋。

我们直接实现Servlet接口,程序员几乎只用操作一个service方法,其他的“多余”了

当前项目中的程序使用缺省适配器模式,代码优雅

那写个类来实现这个接口会用到的部分方法,我们再来继承这个类就可以了啊?

这个类就是抽象类,因为普通类实现接口,必须覆写全部接口方法,而抽象类可以不用,它可以选择留出关键方法让子类去覆写而子类不用管其他的方法,还可以追加普通方法提供给子类使用。

这个抽象类就是适配器。

设计模式的分类:

  • 创建型: 解决对象的创建问题
  • 行为型: 该模式与方法、行为、算法有关的设计模式
  • 结构型: 更多类,更多的对象组合成更大的结构解决某个特定的问题
你听说过哪些设计模式?
  • Gof95(1995年, 四人组提出的23种设计模式)

    • 单例模式
    • 工厂模式
    • 适器模式
    • 迭代模式[集合]
    • 策略模式[集合]
    • 装饰器模式[I0流]
  • JavaEE设计模式

Servlet的适配器模式

定义一个抽象类GenericServlet来充当适配器

package com.gkd.javeee;
import ...
public abstract class GenericServlet implements Servlet {
	
	private ServletConfig config;
	
	@Override
	public void destroy() {
	}

	@Override
	public ServletConfig getServletConfig() {
		return config;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
	}

	@Override
	public abstract void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException; 

	//------------------扩展普通方法增强子类------------------
	
	public ServletContext getServletContext( ) {
		return this.getServletConfig().getServletContext();
	}
	
}

真正的业务servlet来继承这个抽象类:

package com.gkd.javeee;
import ...
public class MyServlet extends GenericServlet {

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("hhhh");
	}
}
现在有一个问题:
  • Servlet子类想要在初始化时执行一些操作怎么办?比如记录日志。

正常来说,子类覆写抽象类GenericServlet中的普通方法init()方法即可,但现在init方法希望不被人覆写,加上了关键字final

public abstract class GenericServlet implements Servlet {
    ...
    public final void init(ServletConfig config) throws ServletException {
		this.config = config;
	}
	...
}

现在我们不能覆写inti()方法了,但是我们能覆写普通方法啊,只要能让这个普通方法在初始化时执行,不一样达到目的在初始化时执行了一些操作吗

可以这么做:

public abstract class GenericServlet implements Servlet {
    ...
    public final void init(ServletConfig config) throws ServletException {
		this.config = config;
		this.hhh();
	}
	
	public void hhh() {}
	...
}

这样我们在子类只要覆写hhh()方法就可以了,不过hhh()命名最好命为init(),以达到望文知义的目的。

上面的适配器是我们自己写的,但是sun公司其实已经帮我们写了一个javax.Servlet.GenericServlet

//sun公司提供的适配器中的init()方法
public final void init(ServletConfig config) throws ServletException {
	this.config = config;
	this.init();
}

Sun公司提供的适配器GenericServlet的init()方法没有加关键字final,也就是子类可以直接覆写init()方法。

如果子类覆写了init()方法,那适配器init()方法中的this.config = config;语句就不会执行,除非子类覆写的时候第一句写上super.init(config)

(super关键字代表父类,在这里有点像把父类方法的代码整合到子类要重写的方法里。这是JavaSE关键字super的知识了)

sun公司考虑了这一点,所以为了方便程序员在子类覆写init()方法,就用了this.hhh()的操作,让程序员覆写的其实是个普通方法,不用写super.init(config),父类的方法中的代码一样可以被执行到。

真是个好想法啊!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值