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

一:背景介绍

现在公司对高端人才的需求越来越大,我们不止需要如何写面向过程的代码,还要知道面向对象的代码怎么写,于是以一个简单的业务场景来理解由面向过程到面向对象是如何进行转换的
在这里插入图片描述

二:思路&方案

1.面向过程的实现思路

在这里插入图片描述

public class Client {
    public static void main(String[] args) {
        System.out.println("我是米老师,我需要开门");
        System.out.println("好的,米老师,我马上给您开门");
    }
}

在这里插入图片描述

2.面向对象的实现思路一(封装)

首先进行封装,这个开门业务可以抽象出来两个角色,发消息人类和收消息人类,为了业务需要,我们还有一个业务隔离类,还有一个客户端,下图是两种依赖方式。被依赖的人都是自由的。
在这里插入图片描述
举例子:
接收人依赖于发消息人

发送消息人:

public class sendMessager {
    public void sendMessage(){
        System.out.println("我是米老师:我需要开门");
    }
}

接收消息人:

public class receiveMessager {
    private void openDoor(){
        System.out.println("我是何老师:我来开门了");
    }
    public void receiveMessage(sendMessager teacherMi){
        teacherMi.sendMessage();
        this.openDoor();
    }
}

业务封装类:

1、进行业务封装。这个类中的private方法只能通过public方法对外使用,保证了安全,客户端只能访问对外公的方法。
2、可扩充(运算符重载)
3、安全性。

public class Notice {
    private void business(){
        receiveMessager teacherHe = new receiveMessager();
        teacherHe.receiveMessage(new sendMessager());
    }
    public void notice(){
        this.business();
    }
}

客户端类:

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

实现效果:

在这里插入图片描述

重载版本

发消息人

public class Mi {
    public  void  sendMessage(Object object)
    {
        He he = new He();
        //米老师给何老师发消息,米老师依赖何老师
        System.out.println("何老师过来开门");
        he.getMessage(object);
    }

}

接收消息人

public class He {
    private  void  openDoor()
    {
        System.out.println("跑着开门");
    }
    private  void  openDoor(String doorName)
    {
        System.out.println("跑着开"+doorName);
    }
    private  void  openDoor(int once)
    {

        System.out.println("第"+once+"次跑着开门");
    }

    public  void getMessage(Object object)
    {
        if (!object.equals(" ") )
        {
            //如果包含数字
            if (object.toString().matches("[0-9]")){
                object = Integer.parseInt(object.toString());
            }
            String type = object.getClass().getTypeName();
            switch(type)
            {
                case"java.lang.String":this.openDoor(object.toString());
                break;
                case"java.lang.Integer":this.openDoor(Integer.parseInt(object.toString()));
                break;
            }
        }
        //要是没有输入就直接开门,调用无参的方法
        else
        {
            this.openDoor();
        }

    }
}

业务封装类

public class Process {

    private  void start(Object object)
    {
       Mi mi = new Mi();
       mi.sendMessage(object);
    }
    public  void notice(Object object)
    {
        this.start(object);
    }
}

客户端类

public class Client {
    public static void main(String[] args) {
        System.out.println("请输入门的信息");
        Scanner scanner = new Scanner(System.in);
        //可以读空格  next是没有办法读空格的
        Object data = scanner.nextLine();
        Process process = new Process();
        process.notice(data);

    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、事件与委托版(C#版米老师何老师)

在这里插入图片描述

委托类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ebtrust1
{
    public class CatShoutEventArgs : EventArgs
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

接收消息类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ebtrust1
{
    public  class GetMessager
    {
        private string name;
        public GetMessager(string name)
        {
            this.name = name;
        }

        public void getMessage(object sender,CatShoutEventArgs args)
        {
            Console.WriteLine("{0}来了,{1}来开门",args.Name,name);
        
        }
        
    }
}

业务封装类


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ebtrust1
{
    public  class Notice
    {
        private void process()
        {
            SendMessager Mi = new SendMessager("米老师");
            GetMessager He = new GetMessager("何老师");

          //  PrentendGetMessager deaf = new PrentendGetMessager("聋子");

            Console.WriteLine("第一个委托---------------------------------------------------");
            Mi.openDoorEvent += new SendMessager.openDoorEventHandler(He.getMessage);
            Mi.sendMessage();


            Console.Read();

        }

        public void notice()
        {
            this.process();
        
        }

    }


}

发送消息人类


using ebtrust1;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ebtrust1
{
    public class SendMessager
    {
        private string name;
        public SendMessager(string name)
        {
            this.name = name;
        }

        public delegate void openDoorEventHandler(object sender, CatShoutEventArgs args);
        public openDoorEventHandler openDoorEvent;
     
        private void sendMessage1Formly()
        {
            Console.WriteLine("我是{0},请给我开门", name);
            if (openDoorEvent != null)
            {
              CatShoutEventArgs e = new CatShoutEventArgs();
                e.Name = this.name;
                openDoorEvent(this,e);
            }

        }

        public void sendMessage()
        {
            this.sendMessage1Formly();
        }

       

    }
}

客户端:

namespace ebtrust1
{
    class Program
    {
        public static void Main(string[] args)
        {
            Notice notice = new Notice();
            notice.notice();

        }

    }
}

多个委托多个事件

在这里插入图片描述

在这里插入图片描述

接收消息类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace entrust
{
    public class GetMessager
    {
        private string name;
        public GetMessager(string name)
        {
            this.name = name;
        }
        private void openDoor1Formly()
        {
            Console.WriteLine("有人请求开门1,{0}来开门1",name);
        }
        private void openDoor2Formly()
        {
            Console.WriteLine("有人请求开门2,{0}来开门2", name);
        }
        private void closeDoor1Formly()
        {
            Console.WriteLine("有人请求关门1,{0}来关门1", name);
        }

        private void closeDoor2Formly()
        {
            Console.WriteLine("有人请求关门2,{0}来关门2", name);
        }

        public void openDoor1()
        {
            this.openDoor1Formly();
        }

        public void openDoor2()
        {
            this.openDoor2Formly();
        }
        public void closenDoor1()
        {
            this.closeDoor1Formly();
        }


        public void closenDoor2()
        {
            this.closeDoor2Formly();
        }



    }
}

发送消息人类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace entrust
{
    public  class SendMessager
    {
        private string name;
        public SendMessager(string name)
        {
            this.name = name;
        }
        //第一个委托有多个事件
        public delegate void SendMessagerOpenDoorHandler();
        public event SendMessagerOpenDoorHandler sendMessagerOpenDoor1;
        public event SendMessagerOpenDoorHandler sendMessagerOpenDoor2;

        //第二个委托
        public delegate void SendMessagerCloseDoorHandler();
        public event SendMessagerCloseDoorHandler sendMessagerCloseDoor1;
        public event SendMessagerCloseDoorHandler sendMessagerCloseDoor2;
        private void noticeOpenDoor1Formly()
        {
            Console.WriteLine("我是{0},给我开门1", name);
            if (sendMessagerOpenDoor1 != null)
            {
                sendMessagerOpenDoor1();

            } 
        }
        private void noticeOpenDoor2Formly()
        {
            Console.WriteLine("我是{0},给我开门2", name);
            if (sendMessagerOpenDoor2 != null)
            {
                sendMessagerOpenDoor2();

            }

        }
        private void noticeCloseDoor1Formly()
        {
            Console.WriteLine("我是{0},帮我关门1", name);
            if (sendMessagerCloseDoor1 != null)
            {
                sendMessagerCloseDoor1();

            }

        }

        private void noticeCloseDoor2Formly()
        {
            Console.WriteLine("我是{0},帮我关门2", name);
            if (sendMessagerCloseDoor2 != null)
            {
                sendMessagerCloseDoor2();

            }

        }
        public void noticeOpenDoor1()
        {
            this.noticeOpenDoor1Formly();
        }
        public void noticeOpenDoor2()
        {
            this.noticeOpenDoor2Formly();
        }

        public void noticeCloseDoor1()
        {
            this.noticeCloseDoor1Formly();
        }
        public void noticeCloseDoor2()
        {
            this.noticeCloseDoor2Formly();
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace entrust
{
    public class Rabbit
    {
        public string name;
        public Rabbit(string name)
        {
            this.name = name;
        }
        private void noOpenDoor1Formly()
        {
            Console.WriteLine("有人请求开门1,{0}害怕我就跑,我不给你开门1", name);
        }
        private void noOpenDoor2Formly()
        {
            Console.WriteLine("有人请求开门2,{0}害怕我就跑,我不给你开门2", name);
        }
        private void noClosenDoor1Formly()
        {
            Console.WriteLine("有人请求关门1,{0}害怕我就跑,我不给你开门1", name);
        }

        private void noClosenDoor2Formly()
        {
            Console.WriteLine("有人请求关门2,{0}害怕我就跑,我不给你开门2", name);
        }



        public void noOpenDoor1()
        {
           this.noOpenDoor1Formly();
        }
        public void noOpenDoor2()
        {
            this.noOpenDoor2Formly();
        }
        public void noClosenDoor1()
        {
            this.noClosenDoor1Formly();
        }

        public void noClosenDoor2()
        {
            this.noClosenDoor2Formly();
        }
    }


}


事件类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ebtrust1
{
    public class CatShoutEventArgs : EventArgs
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

业务封装类


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace entrust
{
    public class Notice
    {
        private void process()
        {
            Rabbit rbWhite = new Rabbit("小白兔");
            SendMessager teacherFan = new SendMessager("饭老师");
            SendMessager teacherMi = new SendMessager("米老师");
            GetMessager studentZhao = new GetMessager("赵媛");
            GetMessager studentLi = new GetMessager("李媛");
            GetMessager studentDeng = new GetMessager("邓媛");

            Console.WriteLine("第一个委托有两个事件--------------这里的每个事件都对应两个对象的方法");
            teacherMi.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(studentZhao.openDoor1);
            teacherMi.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(studentLi.openDoor1);
            teacherMi.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(rbWhite.noOpenDoor1);
            teacherMi.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(studentZhao.openDoor2);
            teacherMi.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(studentLi.openDoor2);
            teacherMi.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(rbWhite.noOpenDoor2);

            teacherFan.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(studentZhao.openDoor1);
            teacherFan.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(studentLi.openDoor1);
            teacherFan.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(studentZhao.openDoor2);
            teacherFan.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(studentLi.openDoor2);
            teacherFan.sendMessagerOpenDoor1 += new SendMessager.SendMessagerOpenDoorHandler(studentDeng.openDoor1);
            teacherFan.sendMessagerOpenDoor2 += new SendMessager.SendMessagerOpenDoorHandler(studentDeng.openDoor2);

            teacherMi.noticeOpenDoor1();
            teacherMi.noticeOpenDoor2();
            teacherFan.noticeOpenDoor1();
            teacherFan.noticeOpenDoor2();

            Console.WriteLine("第二个委托有2个事件---------------这里的每个事件都对应两个对象的方法");
            teacherMi.sendMessagerCloseDoor1 += new SendMessager.SendMessagerCloseDoorHandler(studentZhao.closenDoor1);
            teacherMi.sendMessagerCloseDoor1 += new SendMessager.SendMessagerCloseDoorHandler(studentLi.closenDoor1);
            teacherMi.sendMessagerCloseDoor2 += new SendMessager.SendMessagerCloseDoorHandler(studentZhao.closenDoor2);
            teacherMi.sendMessagerCloseDoor2 += new SendMessager.SendMessagerCloseDoorHandler(studentLi.closenDoor2);

            teacherMi.noticeCloseDoor1();
            teacherMi.noticeCloseDoor2();

            Console.Read();
        }

        public void notice()
        {
            this.process();
        }
    }
}

namespace entrust
{
    class Program { 
    public static void Main(string[] args)
    {
        Notice notice = new Notice();
        notice.notice();

    }

    }
}


在这里插入图片描述

4.面向对象的实现思路(封装、反射)

在这里插入图片描述

public class SendMessager {
    public void sendMessage(String className,String methodName) throws Exception{
        System.out.println("米老师发消息======");
        //通过反射获取对象和方法
        Class classObj = Class.forName(className);
        Object teacherHe = classObj.newInstance();
        Method methodObj = classObj.getMethod(methodName);
        methodObj.invoke(teacherHe,null);
    }
}

public class ReceiveMessager {
    private void openDoor(){
        System.out.println("接收消息的人:好的,已开门");
    }
    public void receiveMessage(){
        this.openDoor();
    }
}

public class Notice {
    private void business(String className,String methodName) throws Exception{
        SendMessager sendMessager = new SendMessager();
        sendMessager.sendMessage(className, methodName);
    }
    private void getParam() throws  Exception{
        //通过new Scanner(System.in)创建一个Scanner类型的名叫scanner的对象,
        //控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给scanner
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名");
        //nextLine()方法的作用时获取当前行的输入内容,
        //返回得到的是回车键之前的所有字符,包括空格
        String className = scanner.nextLine();
        System.out.println("请输入方法名");
        String methodName = scanner.nextLine();
        this.business(className, methodName);
    }
    public void notice() throws Exception{
        this.getParam();
    }
}

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

在这里插入图片描述

四:总结

面向过程写法只能满足两个人
封装类以后可以通过实例化实现多个人发消息,多个人监听
使用反射以后可以再运行时传参,更加灵活。
“我们关注的是谁来干事,而不是怎么干事”
“我们关注的是多少人来干事,而不是干多少事”

继续深思吧~

使用事件与委托(Events and Delegates)是面向对象编程中常用的设计模式之一,它有许多好处,让我们来看看其中一些主要的优点:

解耦合(Decoupling): 事件与委托模式可以实现对象之间的解耦合。当一个对象需要通知其他对象发生了某个事件时,它只需要触发相应的事件,而不需要关心哪些对象会响应这个事件以及如何处理。其他对象也只需要订阅感兴趣的事件,而不需要关心事件是由哪个对象触发的。这样,对象之间的依赖关系得到了简化,使得代码更加灵活和可维护。

扩展性(Extensibility): 通过事件与委托,我们可以很容易地在不修改已有代码的情况下添加新的功能。当需要添加新的处理逻辑时,只需要编写一个新的方法来处理相应的事件,并订阅这个事件即可。这样,我们可以在不破坏原有功能的基础上,实现功能的扩展和定制。

灵活性和可复用性(Flexibility and Reusability): 事件与委托模式提供了一种灵活的机制来处理事件和回调逻辑。通过委托,我们可以在运行时动态地将方法绑定到事件上,使得事件处理逻辑可以更加灵活和通用。这样,我们可以在不同的场景中复用同一个事件,并为每个场景提供不同的处理逻辑。

代码可读性(Code Readability): 事件与委托模式可以使代码更加简洁和可读。当一个对象触发一个事件时,我们可以直接看到该事件的处理逻辑是通过委托调用的,而不需要详细了解事件的具体实现细节。这样,代码的逻辑更加清晰,易于理解和维护。

事件驱动(Event-Driven)编程: 事件与委托模式是事件驱动编程的基础。在事件驱动编程中,程序的执行流程由事件的发生和处理驱动,而不是通过顺序执行的方式。这种编程方式更加符合现实世界的行为模式,使得代码更加灵活和响应性。

总的来说,事件与委托是一种强大的编程模式,它提供了一种灵活、松耦合的方式来处理事件和回调逻辑。通过使用事件与委托,我们可以实现解耦合、扩展性、灵活性、可复用性和代码可读性等优点,使得代码更加优雅、高效和易于维护。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Circ.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值