本文源碼:GitHub·點(diǎn)這里 || GitEE·點(diǎn)這里
建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁(yè)設(shè)計(jì)師等,應(yīng)用各種網(wǎng)絡(luò)程序開(kāi)發(fā)技術(shù)和網(wǎng)頁(yè)設(shè)計(jì)技術(shù)配合操作的協(xié)同工作。創(chuàng)新互聯(lián)專業(yè)提供成都做網(wǎng)站、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站制作(企業(yè)站、成都響應(yīng)式網(wǎng)站建設(shè)、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗(yàn)的提升,我們力求做到極致!
電競(jìng)是游戲比賽達(dá)到“競(jìng)技”層面的體育項(xiàng)目。利用電子設(shè)備作為運(yùn)動(dòng)器械進(jìn)行的、人與人之間的智力對(duì)抗運(yùn)動(dòng)。通過(guò)電競(jìng),可以提高人的反應(yīng)能力、協(xié)調(diào)能力、團(tuán)隊(duì)精神等。但是不同人群的對(duì)電競(jìng)的持有的觀念不一樣,有的人認(rèn)為電競(jìng)就是沉迷網(wǎng)絡(luò),持反對(duì)態(tài)度,而有的人就比較贊同。下面基于訪問(wèn)者模式來(lái)描述該場(chǎng)景。
public class C01_InScene {
public static void main(String[] args) {
DataSet dataSet = new DataSet() ;
dataSet.addCrowd(new Youth());
dataSet.addCrowd(new MiddleAge());
CrowdView crowdView = new Against() ;
dataSet.display(crowdView);
crowdView = new Approve() ;
dataSet.display(crowdView);
}
}
/**
* 雙分派,不同人群管理
*/
abstract class Crowd {
abstract void accept(CrowdView action);
}
class Youth extends Crowd {
@Override
public void accept(CrowdView view) {
view.getYouthView(this);
}
}
class MiddleAge extends Crowd {
@Override
public void accept(CrowdView view) {
view.getMiddleAgeView (this);
}
}
/**
* 不同人群觀念的管理
*/
abstract class CrowdView {
// 青年人觀念
abstract void getYouthView (Youth youth);
// 中年人觀念
abstract void getMiddleAgeView (MiddleAge middleAge);
}
class Approve extends CrowdView {
@Override
public void getYouthView(Youth youth) {
System.out.println("青年人贊同電競(jìng)");
}
@Override
public void getMiddleAgeView(MiddleAge middleAge) {
System.out.println("中年人贊同電競(jìng)");
}
}
class Against extends CrowdView {
@Override
public void getYouthView(Youth youth) {
System.out.println("青年人反對(duì)電競(jìng)");
}
@Override
public void getMiddleAgeView(MiddleAge middleAge) {
System.out.println("中年人反對(duì)電競(jìng)");
}
}
/**
* 提供一個(gè)數(shù)據(jù)集合
*/
class DataSet {
private List crowdList = new ArrayList<>();
public void addCrowd (Crowd crowd) {
crowdList.add(crowd);
}
public void display(CrowdView crowdView) {
for(Crowd crowd : crowdList) {
crowd.accept(crowdView);
}
}
}
訪問(wèn)者模式是對(duì)象的行為模式,把作用于數(shù)據(jù)結(jié)構(gòu)的各元素的操作封裝,操作之間沒(méi)有關(guān)聯(lián)??梢栽诓桓淖償?shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的不同的操作。主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離,解決數(shù)據(jù)結(jié)構(gòu)和操作耦合問(wèn)題核心原理:被訪問(wèn)的類里面加對(duì)外提供接待訪問(wèn)者的接口。
聲明多個(gè)方法操作,具體訪問(wèn)者角色需要實(shí)現(xiàn)的接口。
實(shí)現(xiàn)抽象訪問(wèn)者所聲明的接口,就是各個(gè)訪問(wèn)操作。
聲明接受操作,接受訪問(wèn)者對(duì)象作為參數(shù)。
實(shí)現(xiàn)抽象節(jié)點(diǎn)所規(guī)定的具體操作。
能枚舉結(jié)構(gòu)中的所有元素,可以提供一個(gè)高層的接口,用來(lái)允許訪問(wèn)者對(duì)象訪問(wèn)每一個(gè)元素。
public class C02_Visitor {
public static void main(String[] args) {
ObjectStructure obs = new ObjectStructure();
obs.add(new NodeA());
obs.add(new NodeB());
Visitor visitor = new VisitorA();
obs.doAccept(visitor);
}
}
/**
* 抽象訪問(wèn)者角色
*/
interface Visitor {
/**
* NodeA的訪問(wèn)操作
*/
void visit(NodeA node);
/**
* NodeB的訪問(wèn)操作
*/
void visit(NodeB node);
}
/**
* 具體訪問(wèn)者角色
*/
class VisitorA implements Visitor {
@Override
public void visit(NodeA node) {
node.operationA() ;
}
@Override
public void visit(NodeB node) {
node.operationB() ;
}
}
class VisitorB implements Visitor {
@Override
public void visit(NodeA node) {
node.operationA() ;
}
@Override
public void visit(NodeB node) {
node.operationB() ;
}
}
/**
* 抽象節(jié)點(diǎn)角色
*/
abstract class Node {
/**
* 接收訪問(wèn)者
*/
abstract void accept(Visitor visitor);
}
/**
* 具體節(jié)點(diǎn)角色
*/
class NodeA extends Node{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA(){
System.out.println("NodeA.operationA");
}
}
class NodeB extends Node{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB(){
System.out.println("NodeB.operationB");
}
}
/**
* 結(jié)構(gòu)對(duì)象角色類
*/
class ObjectStructure {
private List nodes = new ArrayList<>();
public void detach(Node node) {
nodes.remove(node);
}
public void add(Node node){
nodes.add(node);
}
public void doAccept(Visitor visitor){
for(Node node : nodes) {
node.accept(visitor);
}
}
}
BeanDefinitionVisitor類,遍歷bean的各個(gè)屬性;接口 BeanDefinition,定義Bean的各樣信息,比如屬性值、構(gòu)造方法、參數(shù)等等。這里封裝操作bean結(jié)構(gòu)的相關(guān)方法,但卻沒(méi)有改變bean的結(jié)構(gòu)。
public class BeanDefinitionVisitor {
public void visitBeanDefinition(BeanDefinition beanDefinition) {
this.visitParentName(beanDefinition);
this.visitBeanClassName(beanDefinition);
this.visitFactoryBeanName(beanDefinition);
this.visitFactoryMethodName(beanDefinition);
this.visitScope(beanDefinition);
if (beanDefinition.hasPropertyValues()) {
this.visitPropertyValues(beanDefinition.getPropertyValues());
}
if (beanDefinition.hasConstructorArgumentValues()) {
ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());
this.visitGenericArgumentValues(cas.getGenericArgumentValues());
}
}
}
1、優(yōu)點(diǎn)描述
(1) 訪問(wèn)者模式符合單一職責(zé)原則、使程序具有良好的擴(kuò)展性、靈活性;
(2) 訪問(wèn)者模式適用與攔截器與過(guò)濾器等常見(jiàn)功能,數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的場(chǎng)景;
2、缺點(diǎn)描述
(1) 訪問(wèn)者關(guān)注其他類的內(nèi)部細(xì)節(jié),依賴性強(qiáng),違反迪米特法則,這樣導(dǎo)致具體元素更新麻煩;
(2) 訪問(wèn)者依賴具體元素,不是抽象元素,面向細(xì)節(jié)編程,違背依賴倒轉(zhuǎn)原則;
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent