JAVA設(shè)計(jì)模式之訪問者模式原理與用法詳解
本文實(shí)例講述了JAVA設(shè)計(jì)模式之訪問者模式。分享給大家供大家參考,具體如下:
訪問者模式:
一個(gè)作用于某對(duì)象結(jié)構(gòu)中各元素的操作,使你可以在不改變各元素類數(shù)據(jù)結(jié)構(gòu)的前提下增加作用于這些元素的新操作。
結(jié)構(gòu)對(duì)象是訪問者模式必備條件,且這個(gè)結(jié)構(gòu)對(duì)象必須存在遍歷自身各個(gè)對(duì)象的方法。
適用于:數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定,把數(shù)據(jù)結(jié)構(gòu)和作用與其上的其它操作解耦,使得操作相對(duì)自由。
優(yōu)點(diǎn):
1、符合單一職責(zé)原則
2、擴(kuò)展性良好:元素類可以通過接受不同的訪問者來實(shí)現(xiàn)對(duì)不同操作的擴(kuò)展。
缺點(diǎn):
1、如果要增加新元素,則會(huì)讓操作變得更復(fù)雜
2、在一定程序上破壞了封裝性原則
訪問者械五大角色對(duì)象:
1.Visitor 抽象訪問者角色
2.ConcreteVisitor.具體訪問者角色
3.Element 接受訪問操作元素
4.ConcreteElement 具體元素
5.ObjectStructure 結(jié)構(gòu)對(duì)象角色,這是使用訪問者模式必備的角色。
/**
* 抽象訪問者:為該對(duì)象結(jié)構(gòu)中具體元素角色聲明一個(gè)訪問操作接口。
* 該操作接口的名字和參數(shù)標(biāo)識(shí)了發(fā)送訪問請(qǐng)求給具體訪問者的具體元素角色,
* 這樣訪問者就可以通過該元素角色的特定接口直接訪問它。
* @description:
* @date 2016-1-15 下午4:00:29
*/
public interface Visitor {
void visit(Element element);
}
/**
* 具體訪問者角色,實(shí)現(xiàn)Visitor聲明的接口。
* @description:
* @date 2016-1-15 下午4:20:46
*/
public class ConcreteVisitor implements Visitor{
@Override
public void visit(Element element) {
Staff e=(Staff) element;
//比如:加薪的計(jì)算方式:職位*加薪系數(shù)+工齡*對(duì)應(yīng)系統(tǒng)之和 除以10 再乘以現(xiàn)在工資
System.out.println(e.getName()+"要加的薪水是:"+(e.getDegree()*0.8+e.getWorkAges()*0.5)/10*e.getSalary());//
}
}
/**
* 定義一個(gè)接受訪問操作類,訪問者(Visitor)操作函數(shù)的參數(shù)。
* @description:
* @date 2016-1-15 下午3:58:28
*/
public abstract class Element {
public abstract void Acceppt(Visitor visitor);
}
/**
* 具體元素,實(shí)現(xiàn)了抽象元素(Element)所定義的接受操作接口。
* @description:
* @date 2016-1-15 下午4:04:24
*/
public class Staff extends Element {
private String name;
private float salary;
private int workAges;
private int degree;
public Staff(String name, float salary, int workAges, int degree) {
super();
this.name = name;
this.salary = salary;
this.workAges = workAges;
this.degree = degree;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
public int getWorkAges() {
return workAges;
}
public void setWorkAges(int workAges) {
this.workAges = workAges;
}
public int getDegree() {
return degree;
}
public void setDegree(int degree) {
this.degree = degree;
}
@Override
public void Acceppt(Visitor visitor) {
visitor.visit(this);
}
}
/**
* 結(jié)構(gòu)對(duì)象:這是使用訪問者模式必備的角色。
* 它具備以下特性:
* 能枚舉它的元素;
* 可以提供一個(gè)高層接口以允許訪問者訪問它的元素;
* 如有需要,可以設(shè)計(jì)成一個(gè)復(fù)合對(duì)象或者一個(gè)聚集(如一個(gè)列表或無序集合)。
* @description:
* @date 2016-1-15 下午4:26:30
*/
public class StaffObject {
private HashMap<String, Staff> employees;
public StaffObject() {
employees = new HashMap<String, Staff>();
}
public void addEmployee(Staff e) {
if (!employees.containsKey(e.getName())) {
employees.put(e.getName(), e);
}
}
public void removeEmployee(Staff e) {
if (employees.containsKey(e.getName())) {
employees.remove(e);
}
}
public Staff getEmployee(String name) {
return employees.get(name);
}
public void Accept(Visitor v) {
for (Staff e : employees.values()) {
e.Acceppt(v);
}
}
}
測(cè)試類
public class Test {
public static void main(String[] args) {
StaffObject e=new StaffObject();
e.addEmployee(new Staff("張三", 3000f, 2, 1));
e.addEmployee(new Staff("李四", 5000f, 4, 2));
e.addEmployee(new Staff("王五", 8000f, 6, 3));
e.addEmployee(new Staff("沈七", 10000f, 9, 4));
e.Accept(new ConcreteVisitor());
}
}
運(yùn)行結(jié)果:
李四要加的薪水是:1800.0 張三要加的薪水是:540.0 沈七要加的薪水是:7700.0 王五要加的薪水是:4320.0
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
Sleuth+logback 設(shè)置traceid 及自定義信息方式
這篇文章主要介紹了Sleuth+logback 設(shè)置traceid 及自定義信息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
解決springboot遇到autowire注入為null的問題
這篇文章主要介紹了解決springboot遇到autowire注入為null的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03
SpringBoot應(yīng)用監(jiān)控帶郵件警報(bào)的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot應(yīng)用監(jiān)控帶郵件警報(bào)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
SpringBoot+Spring Security+JWT實(shí)現(xiàn)RESTful Api權(quán)限控制的方法
這篇文章主要介紹了SpringBoot+Spring Security+JWT實(shí)現(xiàn)RESTful Api權(quán)限控制的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
java中面向?qū)ο蟮母拍罴爸R(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于java中面向?qū)ο蟮母拍罴爸R(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以參考下。2021-01-01
簡(jiǎn)單了解Thymeleaf語法 數(shù)據(jù)延遲加載使用實(shí)例
這篇文章主要介紹了簡(jiǎn)單了解Thymeleaf語法 數(shù)據(jù)延遲加載使用實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2010-05-05
Java實(shí)現(xiàn)學(xué)生成績(jī)輸出到磁盤文件的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)將學(xué)生成績(jī)輸出到磁盤文件的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-11-11
SpringBoot與Postman實(shí)現(xiàn)REST模擬請(qǐng)求的操作
這篇文章主要介紹了SpringBoot與Postman實(shí)現(xiàn)REST模擬請(qǐng)求的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

