一:背景介绍
现在公司对高端人才的需求越来越大,我们不止需要如何写面向过程的代码,还要知道面向对象的代码怎么写,于是以一个简单的业务场景来理解由面向过程到面向对象是如何进行转换的
二:思路&方案
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(); } }
四:总结
面向过程写法只能满足两个人
封装类以后可以通过实例化实现多个人发消息,多个人监听
使用反射以后可以再运行时传参,更加灵活。
“我们关注的是谁来干事,而不是怎么干事”
“我们关注的是多少人来干事,而不是干多少事”
继续深思吧~