标签:element dal not 构造 并且 原则 面试 art err
既然在春招季。我们举个简历筛选的样例,投简历的都是写本科生、专科生。还有硕士生、高职啊…为了简单就先取前两者。求职者的简历作为Element实现例如以下:
abstract class Student {
//提供对于数据域基本操作的函数
private String name;
private String university;
private String rating;
//让指定的visitor获得操作该对象的权限
public abstract void accept(Visitor visitor);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUniversity() {
return university;
}
public void setUniversity(String university) {
this.university = university;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
}
class Bachelor extends Student{
@Override
public void accept( Visitor visitor ) {
visitor.visit( this );
}
}
class College extends Student{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
由于我们仅仅定义了两种学生,所以接口提供了对于两种Element訪问
interface Visitor{
public void visit ( Bachelor bachelor );
public void visit ( College college );
}
首先筛选简历我们看一下大家的简历都什么样子,那么须要一个ShowVisitor:
class ShowVisitor implements Visitor {
@Override
public void visit(Bachelor bachelor) {
System.out.println("A bachelor\n");
//TODO 可能会有一些特异的操作,我们为了简单就省略了
this.printMessage( bachelor );
}
@Override
public void visit(College college) {
System.out.println(" a college student!\n");
//TODO 同上
this.printMessage( college );
}
public void printMessage ( Student student ){
System.out.println( "Name : " + student.getName()+"\n"
+ "University : " + student.getUniversity()+"\n"
+ "Rating : " + student.getRating() + "\n"
);
}
}
要进行測试,我们首先要构造一个数据集合。也就是角色中相应的ObjectStructure,为了简单我们直接用ArrayList了
public class VisitorEg {
public static void main ( String [] args ){
ArrayList<Student> list = new ArrayList<Student>();
Bachelor bachelor = new Bachelor();
bachelor.setName("llin");
bachelor.setRating("100");
bachelor.setUniversity("Tianjin University");
College college = new College();
college.setUniversity("Tianjin college");
college.setRating("1");
college.setName("dalinge");
list.add ( bachelor );
list.add ( college );
Visitor visitor = new ShowVisitor();
for ( Student student: list ){
student.accept( visitor );
}
}
}
那么好像看不出訪问者模式有什么优势啊!!!并且好费事啊,可是由于你将数据结构和对数据的操作分离了(解耦),所以当我想加入新的操作时,不须要改动原有的类,仅仅须要又一次实现一个visitor就能够了。
所以,我们回到这个样例。这么多人报名,那么究竟有多少本科生呢(假设人数够了,可能直接偷懒仅仅面试本科生了),-_-万恶的这样的HR,所以我们须要一个统计的Visitor:
class SumVisitor implements Visitor{
private int totalBachelor;
SumVisitor(){
super();
totalBachelor = 0;
}
@Override
public void visit(Bachelor bachelor) {
totalBachelor++;
}
@Override
public void visit(College college) {
}
public int getTotal_bachelor() {
return totalBachelor;
}
}
public class VisitorEg {
public static void main ( String [] args ){
ArrayList<Student> list = new ArrayList<Student>();
Bachelor bachelor = new Bachelor();
bachelor.setName("llin");
bachelor.setRating("100");
bachelor.setUniversity("Tianjin University");
College college = new College();
college.setUniversity("Tianjin college");
college.setRating("1");
college.setName("dalinge");
list.add ( bachelor );
list.add ( college );
Visitor visitor = new ShowVisitor();
Visitor visitor1 = new SumVisitor();
for ( Student student: list ){
student.accept( visitor );
student.accept( visitor1);
}
System.out.println( "The total sum of bachelors : "+ ((SumVisitor)visitor1).getTotal_bachelor() );
}
}
达到了要求。却没有改动一行代码,开心!
可是由于訪问者依赖详细实现,而不是依赖抽象。所以违反了依赖倒置原则
由于数据和操作的分离,防止了加入新的操作污染原来的数据结构。
訪问者是一种集中规整模式,特别适合用于大规模重构的项目。在这一个阶段的需求已经非常清晰,原系统的功能点也已经明白。通过訪问者模式能够非常easy把一些功能进行梳理,达到终于目的功能集中化
单分派:一个操作是依据请求者的名称和接收到的參数决定的,在Java有静态绑定和动态绑定,各自是通过重载和覆写实现的。
双分派:双分派意味着得到运行的操作决定于请求的种类和接收者的类型。
正相应于訪问者模式。
Java设计模式(三) Visitor(訪问者)模式及多分派场景应用
标签:element dal not 构造 并且 原则 面试 art err
原文地址:http://www.cnblogs.com/tlnshuju/p/7347785.html