模板模式的定义:
它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现,这样子类才可以不改变算法结构的前提下重新定义改算法的某些特定步骤。
模板模式的核心:
处理的步骤父类中早已定义好,具体的实现延迟到子类中去完成。
模板方法的角色:
1.抽象模板角色:它一般是一个抽象类或者接口,它抽象出操作算法骨架。
2.具体抽象模板角色:它实现了抽象模板角色的方法,它是操作算法骨架业务的具体化。
模板方法的优点:
1.封装不变部分,扩展可变部分。
2.提取了公共代码,便于维护。
3.行为由父类控制,子类实现。
模板方法的缺点:
1.每一个不同的实现都需要一个子类来实现,这样导致类的个数增加。
模板模式的使用场景:
1.实现一个算法时,基本步骤很固定,但是某些部分易变,易变的部分可以抽离出来,由子类实现。
* 匿名内部类:
没有名字,定义在其他类方法中的类
* 作用:把定义子类,重写父类的方法,创建子类对象,合成一步完成
* 把定义实现类,重写接口的抽象方法,创建实现类对象,合成一步完成
* 结果:就是一个子类对象,子类对象没有名字
针对模板方法的缺点,我们使用匿名内部类,扩展模板模式。
如下,两个主要方法,save/find, 保存学生失败(这里暂定姓名为主键,主键冲突),那么进行查询。
测试类:
public class TestInnerClass {
private StudentDao studentDao;
public static void main(String[] args) {
TestInnerClass t = new TestInnerClass();
Student student1 = new Student("1", "张三");
Student s1 = t.saveAndGetStudent(student1);
System.out.println(s1);
Student student2 = new Student("2", "李四");
Student s2 = t.saveAndGetStudent(student2);
System.out.println(s2);
}
public Student saveAndGetStudent(Student s) {
studentDao = new StudentDaoImpl();
//模板模式
return RepositoryUtils.saveOrFind(new RepositoryUtils.function<Student>() {
@Override
public Student save() {
return studentDao.saveStudent(s);
}
@Override
public Student find() {
return studentDao.findStudent(s);
}
});
}
}
0.
public class Student {
private String sId;
private String sName;
public Student() {
}
public Student(String sId, String sName) {
this.sId = sId;
this.sName = sName;
}
public String getsId() {
return sId;
}
public void setsId(String sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
@Override
public String toString() {
return "Student{" +
"sId='" + sId + '\'' +
", sName='" + sName + '\'' +
'}';
}
}
1.
public interface StudentDao {
Student findStudent(Student s);
Student saveStudent(Student s);
}
2.
public class StudentDaoImpl implements StudentDao {
@Override
public Student findStudent(Student s) {
//查库逻辑.. 略
return new Student(
"1",
"张三"
);
}
@Override
public Student saveStudent(Student s) {
//存库逻辑.. 略
if ("张三".equals(s.getsName())) {
throw new DataIntegrityViolationException("主键冲突.");
}
return new Student(
"2",
"李四"
);
}
}
3.
public class RepositoryUtils {
interface function<T> {
T save();
T find();
}
public static <T> T saveOrFind(function<T> function) {
try {
return function.save();
} catch (DataIntegrityViolationException e) {
return function.find();
}
}
}
interface function<T> {
T save();
T find();
}
对接口function的操作,即,把定义实现类,重写接口的抽象方法,创建实现类对象,合成一步完成。
end!
ref:
https://blog.csdn.net/sunshine_0707/article/details/86610368
https://www.cnblogs.com/east7/p/9564917.html