委派模式
委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式,允许对象组合实现与继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态代理,可以理解为全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式属于行为模式,不属于GOF 23种设计模式。
java
import java.util.HashMap;
import java.util.Map;
interface IEmployee{
void doing(String task);
}
class EmployeeA implements IEmployee{
protected String goodAt = "编程";
@Override
public void doing(String task) {
System.out.println("我是员工A,我擅长"+goodAt+",现在开始做"+task+"工作");
}
}
class EmployeeB implements IEmployee{
protected String goodAt = "平面设计";
@Override
public void doing(String task) {
System.out.println("我是员工A,我擅长"+goodAt+",现在开始做"+task+"工作");
}
}
class Leader implements IEmployee{
private Map<String, IEmployee> employee = new HashMap<>();
public Leader(){
employee.put("爬虫",new EmployeeA());
employee.put("海报图",new EmployeeB());
}
@Override
public void doing(String task) {
if(!employee.containsKey(task)){
System.out.println("这个任务"+task+"超出我的能力范围");
return;
}
employee.get(task).doing(task);
}
}
class Boss{
public void command(String task, Leader leader){
leader.doing(task);
}
}
public class Test {
public static void main(String[] args) {
new Boss().command("海报图",new Leader());
}
}
在JDK中有一个典型的委派,JVM在加载类是用的双亲委派模型。
委派模式的优缺点:
优点:通过任务委派能够将一个大型的任务细化,然后通过同一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率。
缺点:任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成混乱。
模板方法模式
模板方法模式(Template Method Pattern)又叫模板模式,是指定义一个操作中的算法框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,属于行为型设计模式。
模板方法模式实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。它非常简单,其实就是类的继承机制,但它却是一个应用非常广泛的模式。
利用模板方法重构JDBC操作:
java
import lombok.Data;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* ORM映射定制化接口
*/
interface RowMapper<T>{
T mapRow(ResultSet rs, int rowNum) throws Exception;
}
abstract class JdbcTemplate{
private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public final List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values){
try{
//1.获取连接
Connection conn = this.getConnection();
//2.创建语句集
PreparedStatement pstm = this.createPrepareStatement(conn,sql);
//3.执行语句
ResultSet rs = this.executeQuery(pstm, values);
//4.处理结果
List<?> result = this.parseResultSet(rs,rowMapper);
//5.关闭结果集
rs.close();
//6.关闭语句集
pstm.close();
//7.关闭连接
conn.close();
return result;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
private List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception {
List<Object> result = new ArrayList<>();
int rowNum = 0;
while(rs.next()){
result.add(rowMapper.mapRow(rs,rowNum++));
}
return result;
}
private ResultSet executeQuery(PreparedStatement pstm, Object[] values) throws SQLException {
for(int i=0;i<values.length;i++){
pstm.setObject(i,values);
}
return pstm.executeQuery();
}
private PreparedStatement createPrepareStatement(Connection conn, String sql) throws SQLException {
return conn.prepareStatement(sql);
}
private Connection getConnection() throws SQLException {
return this.dataSource.getConnection();
}
}
/**
* 创建实体对象
*/
@Data
class Member{
private String username;
private String password;
private String nickname;
private int age;
private String addr;
}
/**
* 数据库操作类
*/
class MemberDao extends JdbcTemplate{
public MemberDao(DataSource dataSource) {
super(dataSource);
}
public List<?> selectAll(){
String sql = "select * from t_member";
return super.executeQuery(sql, new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet rs, int rowNum) throws Exception {
Member member = new Member();
member.setUsername(rs.getString("username"));
member.setPassword(rs.getString("password"));
member.setAge(rs.getInt("age"));
member.setAddr(rs.getString("addr"));
return member;
}
},null);
}
}
public class Test {
public static void main(String[] args) {
MemberDao memberDao = new MemberDao(null);
List<?> result = memberDao.selectAll();
System.out.println(result);
}
}
模板方法模式的优缺点:
优点:
- 利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
- 将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
- 把不变的行为写在父类上,去除子类大重复代码,提供一个很好的代码复用平台,符合开闭原则
缺点:
- 类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
- 类数量的增加,间接地增加了系统实现的复杂度。
- 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。