Java设计模式超详解--代理设计模式(含uml图)

目录

一,初步理解

二,结合题目理解

三,总结


一,初步理解

我们首先来理解一下这张uml图,搞清楚为什么要用代理模式,代理模式基本功能是怎么实现的

先举个例子:大明星都有经纪人,当有剧组想找明星拍戏的时候,都要先找经纪人审核剧本,经纪人检查过后再把剧本转给明星

在这个例子中,经纪人是代理(审核),真正执行拍戏动作的是明星

所以这里通用uml中

ProxyTest

剧组人员,发出请求

Subject

找明星拍戏这件事情,接受剧组的请求

RealSubject

明星拍戏

Proxy

经纪人审核剧本看能不能给明星拍

二,结合题目理解

现设计一个投票管理器,用来管理学生选举班长等活动,其接口 VoteManagerInterface 中

addStudent(Student s) 方法用来添加学生候选人

vote(Student voter,Student select) 用来提交学生voter投了学生select一票,

int getVoteNum(Student s) 方法用来获取某个学生的得票数,

VoteManager 类是一个实现,

要求实现VoteManager的代理类,

控制对VoteManager的访问(每个学生不能多次投其他某学生的票,且学生不能投自己)。

注意: 只需提交VoteManagerProxy 类的实现

代码如下:

java 复制代码
import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

class Student{

    private String sno;

    private String sname;



    public Student(String sno, String sname) {

        this.sno = sno;

        this.sname = sname;

    }

    public String getSno() {

        return sno;

    }



    public void setSno(String sno) {

        this.sno = sno;

    }





}

interface VoteManagerInterface{

    void addStudent(Student s);

    void vote(Student voter,Student select);

    int getVoteNum(Student s);



}

class VoteManager implements  VoteManagerInterface{



    private HashMap<String,Integer> map=new HashMap<String,Integer>();



    @Override

    public void addStudent(Student s) {

        map.put(s.getSno(),0);

    }





    @Override

    public void vote(Student voter, Student select) {

        if(map.containsKey(select.getSno())){

            Integer v=map.get(select.getSno());

            map.put(select.getSno(),v+1);

        }else{

            map.put(select.getSno(),0);

        }

    }



    @Override

    public int getVoteNum(Student s) {

        if(map.containsKey(s.getSno())){

           return map.get(s.getSno());



        }

        return 0;

    }

}



/**只需要提交VoteManagerProxy 类

class  VoteManagerProxy implements VoteManagerInterface{

   .....

}

**/



public class Main{



    public static void main(String[] args){

        Student s1=new Student("001","张三");

        Student s2=new Student("002","李四");

        Student s3=new Student("003","王五");



        VoteManagerInterface v=new VoteManagerProxy(new VoteManager());

        v.addStudent(s1);

        v.addStudent(s2);

        v.addStudent(s3);



        v.vote(s1,s1);

        v.vote(s1,s2);

        v.vote(s1,s2);

        v.vote(s1,s3);

        v.vote(s2,s1);

        v.vote(s3,s2);

        v.vote(s3,s1);

        v.vote(s3,s3);



        System.out.println(v.getVoteNum(s1));

        System.out.println(v.getVoteNum(s2));

        System.out.println(v.getVoteNum(s3));

    }

}

对题目进行初步理解,找出uml所对应的部分

ProxyTest

这里的例子中指的是Student,发出请求

Subject

VoteManagerInterface,统一管理投票行为

RealSubject

VoteManager,实际对投票进行实现的类

Proxy

VoteManagerProxy,用Map整理所有学生投票情况,对投票情况进行审核,主要包括

①有没有投给自己

②有没有重复投给同一个人

画出该题的uml

代码如下

java 复制代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class VoteManagerProxy implements VoteManagerInterface {
    // 持有真实的VoteManager对象
    private VoteManagerInterface voteManager;
    // 记录投票记录:key=投票人学号,value=该投票人投过的候选人学号列表
    private Map<String, List<String>> voteRecords;

    // 构造方法,传入真实的VoteManager实例
    public VoteManagerProxy(VoteManagerInterface voteManager) {
        this.voteManager = voteManager;
        this.voteRecords = new HashMap<>();
    }

    @Override
    public void addStudent(Student s) {
        // 直接转发给真实类
        voteManager.addStudent(s);
    }

    @Override
    public void vote(Student voter, Student select) {
        // 1. 获取投票人和被投票人的学号(核心标识)
        String voterSno = voter.getSno();
        String selectSno = select.getSno();

        // 2. 校验规则1:不能投自己
        if (voterSno.equals(selectSno)) {
            return; // 投自己,直接返回,不执行投票
        }

        // 3. 校验规则2:不能重复投同一个候选人
        // 初始化当前投票人的投票记录(如果没有的话)
        if (!voteRecords.containsKey(voterSno)) {
            voteRecords.put(voterSno, new ArrayList<>());
        }
        List<String> votedList = voteRecords.get(voterSno);
        // 如果已经投过该候选人,直接返回
        if (votedList.contains(selectSno)) {
            return;
        }

        // 4. 校验通过:记录投票记录,转发投票请求给真实类
        votedList.add(selectSno);
        voteManager.vote(voter, select);
    }

    @Override
    public int getVoteNum(Student s) {
        // 直接转发给真实类
        voteManager.getVoteNum(s);
        return voteManager.getVoteNum(s);
    }
}

三,总结

代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。

设计模式系列持续更新,欢迎关注博主~

希望对大家有用,祝您开心~(o゜▽゜)o☆,有问题欢迎交流,俺会改的✊

相关推荐
小CC吃豆子21 分钟前
Java数据结构与算法
java·开发语言
晨旭缘22 分钟前
后端日常启动及常用命令(Java)
java·开发语言
CodeAmaz23 分钟前
ArrayList 底层原理
java·arraylist
山峰哥23 分钟前
3000字深度解析:SQL调优如何让数据库查询效率提升10倍
java·服务器·数据库·sql·性能优化·编辑器
tkevinjd24 分钟前
JUC2(多线程中常用的成员方法)
java
天天摸鱼的java工程师30 分钟前
工作中 Java 程序员如何集成 AI?Spring AI、LangChain4j、JBoltAI 实战对比
java·后端
星辰_mya30 分钟前
RockerMQ之commitlog与consumequeue
java·开发语言
__万波__31 分钟前
二十三种设计模式(二十二)--策略模式
java·设计模式·策略模式
不想上班的小吕32 分钟前
采购申请创建(BAPI_PR_CREATE/BAPI_REQUISITION_CREATE)
java·服务器·数据库
专注VB编程开发20年35 分钟前
压栈顺序是反向(从右往左)的,但正因为是反向压栈,所以第一个参数反而离栈顶(ESP)最近。
java·开发语言·算法