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

简介: 案例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();
    }
}

四:总结

面向过程写法只能满足两个人

封装类以后可以通过实例化实现多个人发消息,多个人监听

使用反射以后可以再运行时传参,更加灵活。

“我们关注的是谁来干事,而不是怎么干事”

“我们关注的是多少人来干事,而不是干多少事”

继续深思吧~


相关文章
|
uml
UML之配置图(部署图)
UML之配置图(部署图)
920 1
|
3月前
|
测试技术 数据库 uml
软考中级软件设计师专项-UML图篇
UML(统一建模语言)是一种用于软件系统建模的标准化语言,能够清晰表达系统的静态结构与动态行为。其核心包括三类构造块:事物、关系和图。事物分为结构事物、行为事物、分组事物和注释事物;关系包括依赖、关联、泛化和实现;图则涵盖了类图、对象图、用例图、序列图、通信图、状态图、活动图、构件图和部署图等,分别用于静态建模、动态建模和物理建模。
370 1
软考中级软件设计师专项-UML图篇
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch基础之网络模块torch.nn中函数和模板类的使用详解(附源码)
PyTorch基础之网络模块torch.nn中函数和模板类的使用详解(附源码)
1386 0
|
2月前
|
机器学习/深度学习 PyTorch TensorFlow
TensorFlow与PyTorch深度对比分析:从基础原理到实战选择的完整指南
蒋星熠Jaxonic,深度学习探索者。本文深度对比TensorFlow与PyTorch架构、性能、生态及应用场景,剖析技术选型关键,助力开发者在二进制星河中驾驭AI未来。
661 13
|
SQL XML Java
tk.Mybatis 扩展通用mapper接口
tk.Mybatis 扩展通用mapper接口
|
Rust
【一起学Rust · 项目实战】命令行IO项目minigrep——接收命令行参数与读取文件内容
【一起学Rust · 项目实战】命令行IO项目minigrep——接收命令行参数与读取文件内容
235 0
【一起学Rust · 项目实战】命令行IO项目minigrep——接收命令行参数与读取文件内容
|
SQL
HiveSql数据比对通用写法
hivesql进行两张表的数据对比
216 2
|
机器学习/深度学习 PyTorch 算法框架/工具
Pytorch学习笔记(八):nn.ModuleList和nn.Sequential函数详解
PyTorch中的nn.ModuleList和nn.Sequential函数,包括它们的语法格式、参数解释和具体代码示例,展示了如何使用这些函数来构建和管理神经网络模型。
2104 1
|
存储 安全 C语言
C语言中的共用体与结构体的区别
C语言中的共用体与结构体的区别
449 3
|
安全 Java C++
CAS自旋锁到底是什么?为什么能实现线程安全?
本文是博主对多线程学习总结记录,希望对大家有所帮助。
1550 0
CAS自旋锁到底是什么?为什么能实现线程安全?