JAVA設(shè)計(jì)模式之訪問者模式原理與用法詳解
本文實(shí)例講述了JAVA設(shè)計(jì)模式之訪問者模式。分享給大家供大家參考,具體如下:
訪問者模式:
一個(gè)作用于某對象結(jié)構(gòu)中各元素的操作,使你可以在不改變各元素類數(shù)據(jù)結(jié)構(gòu)的前提下增加作用于這些元素的新操作。
結(jié)構(gòu)對象是訪問者模式必備條件,且這個(gè)結(jié)構(gòu)對象必須存在遍歷自身各個(gè)對象的方法。
適用于:數(shù)據(jù)結(jié)構(gòu)相對穩(wěn)定,把數(shù)據(jù)結(jié)構(gòu)和作用與其上的其它操作解耦,使得操作相對自由。
優(yōu)點(diǎn):
1、符合單一職責(zé)原則
2、擴(kuò)展性良好:元素類可以通過接受不同的訪問者來實(shí)現(xiàn)對不同操作的擴(kuò)展。
缺點(diǎn):
1、如果要增加新元素,則會(huì)讓操作變得更復(fù)雜
2、在一定程序上破壞了封裝性原則
訪問者械五大角色對象:
1.Visitor 抽象訪問者角色
2.ConcreteVisitor.具體訪問者角色
3.Element 接受訪問操作元素
4.ConcreteElement 具體元素
5.ObjectStructure 結(jié)構(gòu)對象角色,這是使用訪問者模式必備的角色。
/** * 抽象訪問者:為該對象結(jié)構(gòu)中具體元素角色聲明一個(gè)訪問操作接口。 * 該操作接口的名字和參數(shù)標(biāo)識(shí)了發(fā)送訪問請求給具體訪問者的具體元素角色, * 這樣訪問者就可以通過該元素角色的特定接口直接訪問它。 * @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ù)+工齡*對應(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)對象:這是使用訪問者模式必備的角色。 * 它具備以下特性: * 能枚舉它的元素; * 可以提供一個(gè)高層接口以允許訪問者訪問它的元素; * 如有需要,可以設(shè)計(jì)成一個(gè)復(fù)合對象或者一個(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); } } }
測試類
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緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)
MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架。接下來通過本文給大家介紹mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié),需要的朋友可以參考下2017-02-02教你一步到位部署運(yùn)行MyBatis3源碼(保姆級(jí))
一個(gè)框架的運(yùn)行流程從最簡單的一個(gè)helloworld來看其源碼就能了解到框架的原理是什么,這篇文章主要給大家介紹了關(guān)于如何一步到位部署運(yùn)行MyBatis3源碼的相關(guān)資料,需要的朋友可以參考下2022-06-06Java web項(xiàng)目啟動(dòng)Tomcat報(bào)錯(cuò)解決方案
這篇文章主要介紹了Java web項(xiàng)目啟動(dòng)Tomcat報(bào)錯(cuò)解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07SpringBoot和Vue實(shí)現(xiàn)動(dòng)態(tài)二維碼的示例代碼
二維碼在現(xiàn)代社交和營銷活動(dòng)中被廣泛使用,本文主要介紹了SpringBoot和Vue實(shí)現(xiàn)動(dòng)態(tài)二維碼的示例代碼,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02