访问者模式的使用条件比较苛刻
主要可以以用于新增访问者时只需要新增一个访问者类,原有代码无需修改,增加一个被访问者时只需增加一个访问方法并在具体访问者中实现,源码同样不需要改变,符合开闭原则
通过访问者和被访问者集中到对象结构供访问者访问的方式使得类的职责更加明确,同一个结构对象可供多个访问者访问,实现代码的复用
package com.linewell.modeldesign.visitor
/**
* 某公司欲为某高校开发一套奖励审批系统,该系统可以实现教师奖励和学生奖励的审批
* 如果教师发表论文超过10篇或者学生发表论文超过2篇,就可以评科研奖
* 如果教师教学反馈分大于90分或者学生平时成绩大于90分就可以评选成绩优秀奖
* 判断集合内的教师或者学生是否符合获奖要求
* Created by ctao on 2015/9/2.
*
*
* 设计思路:
* 可以采用访问者模式
* 奖励审批过程其实可以将奖项看成访问者,将角色看作被访问者,将角色加入角色队列,对每一个角色进行访问
* 所以一共可以抽象出抽象被访问者:人物类,具体被访问者:学生类和老师类
* 抽象访问者:奖项类,具体访问者:科研奖项和成绩优秀奖项
* 对象结构:角色类集合
*/
/**
* 人物类:抽象被访问者
* @param name 姓名
*/
sealed abstract class Person(val name: String) {
def applyAward(award: Award)
}
/**
* 学生,具体角色
* @param name 姓名
* @param thesisNum 论文数
* @param testScore 平时成绩
*/
case class Student(override val name: String, thesisNum: Int, testScore: Double) extends Person(name) {
override def applyAward(award: Award): Unit = award.judge(this)
}
/**
* 老师,具体角色
* @param name 姓名
* @param thesisNum 论文数
* @param feedbackScore 反馈分数
*/
case class Teacher(override val name: String, thesisNum: Int, feedbackScore: Double) extends Person(name) {
override def applyAward(award: Award): Unit = award.judge(this)
}
package com.linewell.modeldesign.visitor
/**
* 奖项:访问者
* Created by ctao on 2015/9/3.
*/
sealed trait Award {
/**
* 评选方法:原有做法
* 问题是如果此时面向抽象对象编程那么增加一个新的角色将修改原来的代码,不符合开闭原则
* 所以在这里应该面对具体人物编程
* def judge(person: Person)
* 如果此时增加一个奖项那就增加一个类
* 如果此时增加一个角色,那么就增加一个评选方法
* 原有代码不需要修改
**/
/**
* 对学生的评选
* @param person 学生
*/
def judge(person: Student): Unit
/**
* 对老师的评选
* @param person 老师
*/
def judge(person: Teacher): Unit
}
/**
* 将定义的子奖项放入奖项的伴生对象
* 就可以实现封装
*/
object Award {
/**
* 简单工厂
* @param award 奖项名
* @return 奖项子对象
*/
def apply(award: String) = award match {
case a if a.equalsIgnoreCase("PerformanceAward") => PerformanceAward
case a if a.equalsIgnoreCase("ResearchAward") => ResearchAward
case _ => Thread sleep 1
throw new ClassNotFoundException("没有该奖项")
}
/**
* 成绩优秀奖项:具体访问者
*/
case object PerformanceAward extends Award {
/**
* 原有做法
* override def judge(person: Person): Unit = person match {
* case p if p.isInstanceOf[Student] => val student = p.asInstanceOf[Student]
* student.testScore match {
* case score if score > 90 => println(s"恭喜${student.name}同学获得成绩优秀奖")
* case _ => println(s"很遗憾,${student.name}同学在本次成绩优秀奖项的评选中落选了")
* }
*
* case p if p.isInstanceOf[Teacher] => val teacher = p.asInstanceOf[Teacher]
* teacher.feedbackScore match {
* case score if score > 90 => println(s"恭喜${teacher.name}老师获得成绩优秀奖")
* case _ => println(s"很遗憾,${teacher.name}老师在本次成绩优秀奖项的评选中落选了")
* }
* }
*/
/**
*
* @param person 学生
*/
override def judge(person: Student): Unit = person.testScore match {
case score if score > 90 => println(s"恭喜${person.name}同学获得成绩优秀奖")
case _ => println(s"很遗憾,${person.name}同学在本次成绩优秀奖项的评选中落选了")
}
/**
*
* @param person 老师
*/
override def judge(person: Teacher): Unit = person.feedbackScore match {
case score if score > 90 => println(s"恭喜${person.name}老师获得成绩优秀奖")
case _ => println(s"很遗憾,${person.name}老师在本次成绩优秀奖项的评选中落选了")
}
}
/**
* 科研奖项:具体访问者
*/
case object ResearchAward extends Award {
/**
* 原有做法
* override def judge(person: Person): Unit = person match {
* case p if p.isInstanceOf[Student] => val student = p.asInstanceOf[Student]
* student.thesisNum match {
* case num if num > 2 => println(s"恭喜${student.name}同学获得科研奖")
* case _ => println(s"很遗憾,${student.name}同学在本次科研奖项的评选中落选了")
* }
* case p if p.isInstanceOf[Teacher] => val teacher = p.asInstanceOf[Teacher]
* teacher.thesisNum match {
* case num if num > 10 => println(s"恭喜${teacher.name}老师获得科研奖")
* case _ => println(s"很遗憾,${teacher.name}老师在本次科研奖项的评选中落选了")
* }
*
* }
*/
/**
*
* @param person 学生
*/
override def judge(person: Student): Unit = person.thesisNum match {
case num if num > 2 => println(s"恭喜${person.name}同学获得科研奖")
case _ => println(s"很遗憾,${person.name}同学在本次科研奖项的评选中落选了")
}
/**
*
* @param person 老师
*/
override def judge(person: Teacher): Unit = person.thesisNum match {
case num if num > 10 => println(s"恭喜${person.name}老师获得科研奖")
case _ => println(s"很遗憾,${person.name}老师在本次科研奖项的评选中落选了")
}
}
}
package com.linewell.modeldesign.visitor
import scala.collection.mutable.ArrayBuffer
/**
* 对象集合类
* Created by ctao on 2015/9/3.
*/
class PersonBuffer {
/**
* 存放需要参加评选的人物
*/
private var persons = new ArrayBuffer[Person]()
/**
* 添加需要评选的人物
* @param person 人物
*/
def addPerson(person: Person) = person match {
case p if persons.exists(p.eq(_)) => println(s"${p.name}已经在评选组内,不要重复申请")
case _ => persons += person
}
def applyAward(award: Award) = persons.foreach(_.applyAward(award))
}
package com.linewell.modeldesign.visitor
/**
* 访问者模式测试客户端
* Created by ctao on 2015/9/3.
*/
object Client extends App {
/**
* 人物
*/
val ct: Person = Student("ct", 8, 91)
val pk: Person = Student("pk", 2, 70)
val cwy: Person = Student("cwy", 3, 66)
val wkl: Person = Student("wkl", 1, 80)
val wzh: Person = Teacher("wzh", 11, 88)
val kmj: Person = Teacher("kmj", 5, 91)
/**
* 对象结构
*/
val personBuffer = new PersonBuffer
/**
* 添加评选对象
*/
personBuffer.addPerson(ct)
personBuffer.addPerson(ct)
personBuffer.addPerson(pk)
personBuffer.addPerson(cwy)
personBuffer.addPerson(wkl)
personBuffer.addPerson(wzh)
personBuffer.addPerson(kmj)
/**
* 成绩优秀奖的评选
*/
val performance = Award("PerformanceAward")
personBuffer.applyAward(performance)
/**
* 科研奖的评选
*/
val research= Award("ResearchAward")
personBuffer.applyAward(research)
}
相关推荐
设计模式C++学习之访问者模式(Visitor)
java设计模式之访问者模式,通过实际例子说明访问者模式原理和适用场景;
访问者模式,你绝对会用到的模式,值得学习,通俗易懂的实例,原理和运用都说明白了。
设计模式之访问者模式Java版本的实现和UML类图
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...
设计模式 - 访问者模式
设计模式-访问者模式(讲解及其实现代码)
java 设计模式之访问者模式.rarjava 设计模式之访问者模式.rar
ios 平台实现设计模式-访问者模式,以最简单的代码实现访问者模式讲解,主旨在于了解访问者模式,博客:http://blog.sina.com.cn/s/blog_161d504630102wwxe.html
设计模式的访问者模式的例子,希望对大家有用~~~~~~~~
访问者模式(Visitor) 用意:适用于数据结构相对未定的系统,把数据结构和作用于结构上的操作间的耦合解开。
最简单的访问者模式讲解代码,设计模式可看看博客中简介http://blog.sina.com.cn/s/blog_161d504630102wxis.html
Java设计模式27访问者模式.pdf
23种设计模式之访问者模式对访问者模式进行了简单的介绍,并附带了例子程序,和大家分享
java常用设计模式-访问者模式
设计模式之建造者模式代码示例,
访问者设计模式,定义及其代码都有展示.讲解很清晰。
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
设计模式之中介者模式java代码实现 设计模式之中介者模式