案例18-面向对象之开门小例子

简介: 面向对象之开门小例子

一:概念说明

面向对象

       面向对象是一种软件开发的方法论和编程范式,它将现实世界中的事物抽象为对象,并通过对象之间的交互来实现系统的设计和开发。

       面向对象的核心思想是将系统看作是一组相互作用的对象的集合。每个对象都有自己的属性(数据)和行为(方法),并且能够与其他对象进行交互。对象之间通过消息传递来进行通信和协作,每个对象根据接收到的消息来执行相应的操作。

二:背景介绍

       米老师需要开办公室的门,需要进入办公室进行工作。这时候需要何老师来进行开门的操作。

三:思路&方案

1.面向过程

       何老师管理钥匙,米老师需要开门,何老师把钥匙方法一个位置上。米老师到壹佰之后去拿钥匙 自己去执行开门的操作。

2.面向对象(依赖)

       米老师到达公司之后,米老师喊一下何老师打开办公室的门,何老师听到消息之后就过来开门了。

3.C#事件与委托

       C#事件与委托是借助于大话设计模式中的猫和老鼠的例子来实现的,这个例子达到的效果是猫一叫老鼠就跑,但是事先猫和老鼠并不认识这时候就需要有一个委托人来使猫和老鼠有这种依赖关系。

4.面向对象(反射)

       米老师到达公司之后,米老师喊了一下给我开一下办公室的门,听到米老师消息的任意一个老师都可以过来开门。

5.面向对象(Java事件与委托)

       借助于C#版本的时间与委托,来实现米老师需要一个老师来开门,最终是哪个老师来开门是程序运行的时候才确定的。减少了米老师和其他老师之间的耦合。

四:实现过程

1.面向过程:原本何老师的作用交给我了米老师来完成。

代码实现

public class Client {
    public static void main(String[] args) {
        System.out.println("米老师:我需要开门");
        System.out.println("何老师:米老师,钥匙放在前台了,您开一下吧");
        System.out.println("米老师:去前台拿钥匙自己去开门了");
    }
}

效果展示

d2f707113c25469ab7d6f153e321c056.png

2.面向对象:把开门的方法完全交个何老师,米老师不需要有开门的操作

代码实现

客户端

public class Client {
    public static void main(String[] args) {
        Notice notice=new Notice();
        notice.notice();
    }
}

业务封装类

public class Notice {
    private void TeahcerMiDependTeacherHeBusiness(){
         ReceiveMsg receiveMsgTeacherHe=new ReceiveMsg();
         receiveMsgTeacherHe.receiveMsg(new SendMsg());
    }
    public void notice(){
        this.TeahcerMiDependTeacherHeBusiness();
    }
}

发消息类

public class SendMsg {
    public void sendMsg(){
        System.out.println("米老师:我需要开一下门");
    }
}

收消息类

public class ReceiveMsg {
    private void open(){
        System.out.println("何老师:开门中。。。。。。门已打开");
    }
    public void receiveMsg(SendMsg sendMsgTeacherMi){
        sendMsgTeacherMi.sendMsg();
        this.open();
    }
}

效果展示

da52d2075e544fb1b8660006980015fc.png

3.C#事件与委托:猫叫老鼠跑,猫和老鼠互不认识

代码实现

客户端

static void Main(string[] args)
{
    //实例化对象
    Cat cat = new Cat("Tom");
    Mouse mouse1 = new Mouse("Jerry");
    Mouse mouse2 = new Mouse("Jake");
    //事件和方案进行绑定,执行事件时调用绑定的方法
    cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
    cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
    cat.Shout();
    Console.Read();
}

猫类

namespace 委托与事件
{
    internal class Cat
    {
        private string name;
        public Cat(string name)
        {
            this.name = name;
        }
        //声明委托
        public delegate void CatShoutEventHandler();
        //声明事件,事件的类型为委托类型。
        public event CatShoutEventHandler CatShout;
        public void Shout()
        {
            Console.WriteLine("喵,我是{0}",name);
            //判断是否拥有CatShout事件
            if (CatShout != null)
            {
                CatShout();
            }
        }
    }
}

老鼠类

namespace 委托与事件
{
    internal class Mouse
    {
        private string name;
        public Mouse(string name)
        {
            this.name = name;
        }
        public void Run()
        {
            Console.WriteLine("老猫来了,{0}快跑!",name);
        }
    }
}

效果展示

50d5e330d0de4e3eba7044aac434be83.png

4.面向对象(反射):米老师不仅仅可以叫何老师来开门,也可以叫其他老师开门

代码实现

客户端

public class Client {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
        Notice notice=new Notice();
        notice.notice();
    }
}

业务封装类

public class Notice {
    private void MiAndHeBusiness() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException, IOException {
        TeacherHe teacherHe = new TeacherHe();
        teacherHe.acceptMessage();
    }
    public void notice() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {
        this.MiAndHeBusiness();
    }
}

发送消息类

public class TeacherMi {
    public void sendMsg(){
        System.out.println("我需要开一下门");
    }
    public void sendMsgAndKey(String room,String key){
        System.out.println("这是"+room+"以后"+key+"由你来保管,快开门吧");
    }
    public static void sendMessage(){
        System.out.println("帮我开一下办公室的门");
    }
}

接收消息类

public class TeacherHe {
    public void acceptMessage() throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
        this.acceptMsg();
    }
    private void acceptMsg() throws IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入要依赖的类路径");
        String className=br.readLine();
        System.out.println("请输入要执行的方法");
        String methodName=br.readLine();
        System.out.println("请输入方法要传入的第一个参数");
        String roomName=br.readLine();
        System.out.println("请输入方法要传入的第一个参数");
        String keyName=br.readLine();
        br.close();
        Class sendMsgClass=Class.forName(className);
        Method sendMsgMethod= sendMsgClass.getMethod(methodName,String.class,String.class);
        Object sender =  sendMsgClass.newInstance();
        sendMsgMethod.invoke(sender,roomName,keyName);
        System.out.println("收到了,我来开门了");
        this.open();
    }
    private void open(){
        System.out.println("正在开门中。。。。。。。。。。。 门开了");
    }
}

效果展示

4ce1edd6c02e499c8058cd8c258e707b.png

5.面向对象(Java事件与委托)

类图展示

dfa72a0b10d84a3c9556efa4f01e8f23.png

代码实现

客户端

public class Client {
    public static void main(String[] args) throws Exception {
        Notice notice=new Notice();
        notice.notice();
    }
}

notice类

public class Notice {
    /**
    * @Author:Wuzilong
    * @Description:写基本的逻辑,如何实现的方法
    * @CreateTime: 2023/6/28 8:14
    * @param:
    * @return:
    **/
    private void compositeBusiness() throws Exception {
        GetParam getParam=new GetParam();
        List<String> param = getParam.getParam();
        BusinessMethod businessMethod=new BusinessMethod();
        if(param.size()==2){
            businessMethod.businessMethod(param.get(0),param.get(1));
        }else{
            businessMethod.businessMethod(param.get(0),param.get(1),param.get(2));
        }
    }
    public void notice() throws Exception {
        this.compositeBusiness();
    }
    /**
    * @Author:Wuzilong
    * @Description: 获取控制台传入的参数
    * @CreateTime: 2023/6/28 8:15
    * @param:
    * @return:
    **/
    class GetParam{
        private List<String> getParam() throws Exception{
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入send的对象名.方法,例如:OpenDoorMHListenerConfigV2.SendMessager.sendMessage");
            String sendCNAMN=scanner.nextLine();
            System.out.println("请输入receive的对象名.方法,例如:OpenDoorMHListenerConfigV2.TeacherHe.receiveMessage");
            String receiveFirst=scanner.nextLine();
            System.out.println("现在还可以设置一个receive对象是否需要,回复y则为继续输入");
            List<String> paramList=new ArrayList<>();
            paramList.add(sendCNAMN);
            paramList.add(receiveFirst);
            if(scanner.nextLine().equals("y")){
                System.out.println("请输入第二个receive对象的对象名.方法,例如:OpenDoorMHListenerConfigV2.TeacherLiang.receiveMessage");
                String receiveSecond = scanner.nextLine();
                paramList.add(receiveSecond);
                return paramList;
            }
            return paramList;
        }
    }
    class BusinessMethod{
        private void businessMethod(String sendCNameAndMName,String receiveCNameAndMName) throws Exception {
            Listener listener = new Listener();
            listener.addSender(sendCNameAndMName);
            listener.addReceiver(receiveCNameAndMName);
            listener.start();
        }
        private void businessMethod(String sendCNameAndMName,String receiveFirst,String  receiveSecond) throws Exception {
            Listener listener = new Listener();
            listener.addSender(sendCNameAndMName);
            listener.addReceiver(receiveFirst);
            listener.addReceiver(receiveSecond);
            listener.start();
        }
    }
}

委托类

public class Delegate {
    //用来存储发消息人匹配的事件对象
    private List<Delegate> receiveMessagerList=new ArrayList<>();
    //用来存储注册进来的对象信息包括 对象本身、要执行的方法和方法的入参
    private List<Triple<Person,Method,Object[]>> personMethodList=new ArrayList<>();
    public Delegate(){}
    public void invoke(){
        this.startMethod();
        for (Delegate delegate:receiveMessagerList){
            delegate.startMethod();
        }
    }
    private void  startMethod(){
        for (Triple<Person, Method, Object[]> personMethodTriple : personMethodList) {
            try {
                personMethodTriple.getMiddle().invoke(personMethodTriple.getLeft(),personMethodTriple.getRight());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public void addReceiveDelegate(Delegate delegate){
        this.receiveMessagerList.add(delegate);
    }
    public void addPerson(String classNameAndMethodName, Object...methodParameter ){
        String className = classNameAndMethodName.substring(0,classNameAndMethodName.lastIndexOf("."));
        String methodName = classNameAndMethodName.substring(classNameAndMethodName.lastIndexOf(".")+1);
        int len=methodParameter.length;
        Class[] methodType = new Class[len];
        for(int i=0;i<len;i++){
            methodType[i]=methodParameter[i].getClass();
        }
        Person tmpPerson=null;
        Method tmpMethod=null;
        try {
            tmpPerson = (Person)Class.forName(className).newInstance();
            tmpMethod=tmpPerson.getClass().getMethod(methodName,methodType);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        this.personMethodList.add(new ImmutableTriple<>(tmpPerson,tmpMethod,methodParameter));
    }
    public static Delegate getInstance(String className){
        Delegate delegate=null;
        try {
            delegate= (Delegate)Class.forName(className).newInstance();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println("创建对象失败");
        }
        return delegate;
    }
}

事件类

public class TeacherHeEvent extends Delegate {
}

监控类

1
public class Listener {
2
    private Map delegateReceiveMap=new HashMap<>();
3
    private Map delegateSendMap=new HashMap<>();
4
    DelegateRelation delegateRelation=new DelegateRelation();
5
    public void addSender(String sendCNameAndMName) throws Exception {
6
        delegateRelation.addDelegate(sendCNameAndMName,delegateSendMap);
7
    }
8
    public void addReceiver(String receiveCNameAndMName)throws Exception  {
9
        delegateRelation.addDelegate(receiveCNameAndMName,delegateReceiveMap);
10
    }
11
    public void start(){
12
        this.matching();
13
        this.execute();
14
    }
15
    /**
16
     * @description: 匹配发消息和收消息人员
17
     * @author: wuzilong
18
     * @date: 2023/6/24 15:47
19
     * @param: []
20
     * @return: void
21
     **/
22
    public void matching(){
23
        delegateRelation.delegateRelation(delegateSendMap,delegateReceiveMap);
24
    }
25
    /**
26
     * @description: 执行匹配后的发消息委托
27
     * @author: wuzilong
28
     * @date: 2023/6/24 15:47
29
     * @param: []
30
     * @return: void
31
     **/
32
    public void execute(){
33
        Set keySet = delegateSendMap.keySet();
34
        for (String key:keySet){
35
            delegateSendMap.get(key).invoke();
36
        }
37
    }
38
    class DelegateRelation{
39
        public void addDelegate(String personName,Map delegateMap)throws Exception{
40
            String className = personName.substring(0,personName.lastIndexOf("."));
41
            if(delegateMap.get(className)==null){
42
                delegateMap.put(className, Delegate.getInstance(new ConfigUtil().get(className)));
43
            }
44
            delegateMap.get(className).addPerson(personName);
45
        }
46
        public void delegateRelation(Map delegateSendMap, Map delegateReceiveMap){
47
            Set receivekeySet = delegateReceiveMap.keySet();
48
            Set sendKeySet = delegateSendMap.keySet();
49
            for (String sendKey:sendKeySet){
50
                for (String receiveKey:receivekeySet){
51
                    delegateSendMap.get(sendKey).addReceiveDelegate(delegateReceiveMap.get(receiveKey));
52
                }
53
            }
54
        }
55
    }
56
}

抽象类:具体的业务对象直接继承Person然后重写方法即可。通过里式替换的方式使用对象

public class Person {
    public void sendMessage(){
    }
    public void receiveMessage(){
    }
}

效果展示

000ac080275b4b20ab165ed03f2cff5e.png

五:总结提升

149b405da3824d7a84d35fb7ff1f51b1.png

       面向过程和面向对象没有好坏之分,只是应用的场景不同。我们之所以要用面向对象的思想是因为我们要为后期的维护考虑,这样我们就需要写出来的代码容易扩展,复用性强。在面向对象的基础上使用反射,使我们的系统更加的灵活,在运行的过程中我们可以让给来开门都可以。


相关文章
|
开发工具 开发者 git
2023 Visual Studio Code 插件推荐:18 个提高开发效率的常用插件
Visual Studio Code (简称VSCode) 是一款强大的开源代码编辑器,它拥有众多功能强大的扩展插件,使得开发者可以根据自己的需求来定制编辑器的功能和外观。在本文中,我们将分享一些非常实用的 VSCode 插件,这些插件将提高您的开发效率,使编码变得更加愉快。
1314 2
|
6月前
|
监控 安全 物联网
RFID工地车辆管理
在工地场景中,RFID技术为车辆管理提供智能化解决方案。通过自动识别与权限控制、实时定位与状态监控、任务分配跟踪等功能,提高管理效率和数据准确性,优化资源配置并降低成本。同时,驾驶员资质审查、安全区域限制等措施增强安全性,实现信息化管理,确保施工进度与现场安全。图文源于网络,侵删!
|
3月前
|
人工智能 自然语言处理 监控
一文看懂开源Coze如何让测试效率飙升
Coze是测试工程师的AI引擎,支持私有部署与零代码测试,提升效率并降低成本。覆盖智能用例生成、数字员工值守、缺陷分析、多模态报告与安全测试五大场景,助力测试智能化转型。
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
184 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
10月前
|
存储 人工智能 运维
内附源码|头部基模企业信赖之选——DMS+Lindorm智能搜索方案
本文为数据库「拥抱Data+AI」系列连载第6篇,针对企业构建智能搜索服务的痛点,介绍如何利用阿里云Data+AI解决方案构建一站式AI搜索服务,深入分析了DMS+Lindorm的智能搜索解决方案。
|
数据采集 运维 算法
大数据项目管理:从需求分析到成果交付的全流程指南
【4月更文挑战第9天】本文介绍了大数据项目从需求分析到成果交付的全过程,包括需求收集与梳理、可行性分析、项目规划、数据准备与处理、系统开发与集成,以及成果交付与运维。文中通过实例展示了如何进行数据源接入、数据仓库建设、系统设计、算法开发,同时强调了需求理解、知识转移、系统运维的重要性。此外,还提供了Python和SQL代码片段,以说明具体技术实现。在大数据项目管理中,需结合业务和技术,灵活运用这些方法,确保项目的成功执行和价值实现。
3238 1
|
缓存 Java 应用服务中间件
【高并发优化手段】基于Springboot项目(二)
【高并发优化手段】基于Springboot项目
1179 0
|
Cloud Native Serverless 测试技术
祝贺!我的同事丁宇获“2023 年度云原生产业领军人物”荣誉称号
祝贺!我的同事丁宇获“2023 年度云原生产业领军人物”荣誉称号
1051 107
|
JSON 关系型数据库 MySQL
MySQL全文搜索与JSON支持:高效检索与灵活数据处理
本文深入探讨了MySQL数据库中的全文搜索与JSON支持,通过详细的代码示例,阐述了全文搜索的原理、全文索引的创建,以及JSON数据类型的使用与操作。全文搜索在数据库中的重要性日益凸显,MySQL提供了全文索引来实现高效的文本数据检索,通过MATCH AGAINST语句,可以轻松地进行全文搜索操作。此外,MySQL的JSON支持为半结构化数据的存储和查询提供了灵活的解决方案,您可以存储JSON对象、数组等数据,并使用JSON函数来查询和修改数据。
1458 0
|
Java 数据库连接 mybatis
shardingsphere集成mybatis/mybatis-plus快速实现简单分片
shardingsphere集成mybatis/mybatis-plus快速实现简单分片
1101 0