- 最近先把简单的模式讲解一下,之前的模式比较难的例子找到好的例子替代之后再放上来,这个模式是23种设计模式最后一个,可能不太常用,所以是最后一个,因为比较好理解,所以先放上来
- 访问者模式原理:
- 雇员管理系统遇到的问题:
- 新操作:年底根据雇员的等级或者休假天数给与补偿
- 代码讲解:
package fangwenzhemoshi;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 13:33
*/
/**
* 雇员类
*/
public class Employee {
private String name;
private float income;
private int vacationDays;
private int degree;
public Employee(String name, float income, int vacationDays,int degree){
this.name = name;
this.income = income;
this.vacationDays = vacationDays;
this.degree = degree;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getIncome() {
return income;
}
public void setIncome(float income) {
this.income = income;
}
public int getVacationDays() {
return vacationDays;
}
public void setVacationDays(int vacationDays) {
this.vacationDays = vacationDays;
}
public int getDegree() {
return degree;
}
public void setDegree(int degree) {
this.degree = degree;
}
}
- 雇员管理:
package fangwenzhemoshi;
import java.util.HashMap;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 13:36
*/
public class Employees {
private HashMap<String, Employee> employees;
public Employees(){
employees = new HashMap<String , Employee>();
}
public void attach(Employee employee){
employees.put(employee.getName(), employee);
}
public void detch(Employee employee){
employees.remove(employee);
}
public Employee getEmpployee(String name){
return employees.get(name);
}
public void getCompensation(){
for(Employee employee:employees.values()){
System.out.println(employee.getName()+"'s compensation is "+ (employee.getDegree() * employee.getVacationDays() * 100));
}
}
}
- 测试:
package fangwenzhemoshi;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 13:45
*/
public class MainTest {
public static void main(String[] args) {
Employees employees = new Employees();
employees.attach(new Employee("Wjx", 19000, 8,1));
employees.attach(new Employee("Jerry", 5000, 10, 2));
employees.attach(new Employee("Jack", 9600, 12, 3));
employees.getCompensation();
}
}
-
将新的功能放到雇员管理这个类:
- 功能是不变的,但是计算补贴的算法如果变化,那么就需要常常修改
-
所以引出访问者模式:
- 在雇员中放一个Accept()访问,就是将访问者注入到对象中,算法有变化等等操作的都独立成一个具体的访问者,那么到时候会利用双重利用的方式完成整个系统的功能的添加和修改
- 访问者模式:对于一组对象,在不改变数据结构的前提下 ,增加作用于这些结构元素新的功能(每个对象补贴的算法就作用于对象的元素)
- 适用于数据结构稳定,他把数据结构和作用于其上的操作解耦,使得操作集合可以相对自由地演化,具体的访问者具体一种操作算法。
-
优点:
-
符合单一职责原则
-
扩展性良好
-
有益于系统的维护和管理
-
-
缺点:
-
增加新的元素变得很困难(具体一个元素类,增加一个新的属性,基于这个新的属性,做一些操作,需要更改算法)
-
破坏封装性(通过访问者注入到每个对象以后,对象必须将数据结构暴露出来)
-
-
代码讲解:
-
Visitor 接收被访问者
Visitor 接收被访问者
package fangwenzhemoshi.fangwenzhe;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 14:18
*/
public interface Visitor {
//把elemt反馈给访问者,
abstract public void Visit(Element element);
}
- Element 被访问者
package fangwenzhemoshi.fangwenzhe;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 14:14
*/
public abstract class Element {
abstract public void Accept(Visitor visitor);
}
- Employee
package fangwenzhemoshi.fangwenzhe;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 14:15
*/
public class Employee extends Element {
private String name;
private float income;
private int vacationDays;
private int degree;
public Employee(String name, float income, int vacationDays,int degree){
this.name = name;
this.income = income;
this.vacationDays = vacationDays;
this.degree = degree;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getIncome() {
return income;
}
public void setIncome(float income) {
this.income = income;
}
public int getVacationDays() {
return vacationDays;
}
public void setVacationDays(int vacationDays) {
this.vacationDays = vacationDays;
}
public int getDegree() {
return degree;
}
public void setDegree(int degree) {
this.degree = degree;
}
//接上访问者之后访问者注入到雇员,把雇员对象给访问者用,第一个将访问者指派给雇员,雇员把自己反馈给访问者双重指派, 将自己暴露给visitor
@Override
public void Accept(Visitor visitor) {
visitor.Visit(this);
}
}
- Employees 雇员管理:
package fangwenzhemoshi.fangwenzhe;
import java.util.HashMap;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 14:21
*/
public class Employees {
private HashMap<String, Employee> employees;
public Employees(){
employees = new HashMap<String , Employee>();
}
public void attach(Employee employee){
employees.put(employee.getName(), employee);
}
public void detch(Employee employee){
employees.remove(employee);
}
public Employee getEmpployee(String name){
return employees.get(name);
}
//将visitor暴露给每一个Employee
public void Accept(Visitor visitor){
for(Employee employee:employees.values()){
employee.Accept(visitor);
}
}
}
- 访问者:
package fangwenzhemoshi.fangwenzhe;
/**
* Created with IntelliJ IDEA.
* Description:
* User: wjx
* Date: 2019-05-12
* Time: 14:20
*/
public class CompensationVisitor implements Visitor {
@Override
public void Visit(Element element) {
Employee employee = (Employee) element;
System.out.println(employee.getName()+"'s compensation is "+ (employee.getDegree() * employee.getVacationDays() * 100));
}
}