《电子邮件》
让我们发邮件吧!
假设您编写了一个向客户发送电子邮件的函数。你最初的函数调用可能是这样的:
sendEmail (emailAddress firstName、lastName bodyText)
对我们的功能有4个输入是可以的,但是如果我们需要添加更多的客户详细信息,就很难管理了。在从事软件项目时,我们发现某些变量倾向于组合在一起。在我们的例子中,“名”、“姓”和“电子邮件地址”代表客户。我们还可以用“名称”、“描述”和“价格”来表示产品,或者用“客户”、“产品”和“日期时间”来表示订单。
让我们把前三个输入归为一个变量。最简单的方法是用结构体:
customer = struct("FirstName", FirstName,"LastName", LastName,"Email",emailAddress);
然后我们的函数调用变成:
bodyText sendEmail(客户)
这样做的好处是,我们现在可以将与客户相关的所有信息作为单个变量传递。如果他们的邮政地址被添加到结构中,我们就可以在我们的sendEmail函数。
顾客身上有什么?
当新的开发人员(或者几周后的您!)再次查看此函数时,缺点就出现了。到底是什么在“客户”结构?他们的名字字段是叫“FirstName”还是“FirstName”?
如果您试图访问一个不存在的字段,您将得到一个错误,但是如果您设置了一个以前不存在的字段,它将被自动添加到结构体中。也许您可以从现有代码中计算出正确的名称,假设它不是太长或太复杂。否则,您将不得不运行一个测试(因为有人写了一个测试,对吧?),并查看在运行时为函数提供了什么。
对于客户,我们至少可以对内容进行有根据的猜测。如果采用更通用的名称(“data”、“metdadata”、“info”),则可能不可能。
这种清晰度的缺乏会一次又一次地浪费开发人员的时间,并可能导致难以追踪的微妙错误。
什么是有效客户?
为解决此问题,可以在客户输入:我们希望确保我们有一个具有正确字段名的标量结构,数据类型是正确的,并且满足任何其他验证规则。例如,电子邮件地址的格式总是“*@*”。*”。
管理这个可能是复杂而费力的。如果不小心,就会导致重复验证的零散代码,并且难以阅读。此外,我们能否保证所有这样的“客户结构”总是有效的?不——对于我们或其他开发人员来说,有可能创建了一个无效的客户结构,并且直到再次运行验证或代码错误时我们才会知道它。
这就形成了第二个错误来源——不是预期格式的数据。常见的问题包括变量为空但不应该为空,或者cellstr应该是字符串数组。
我们需要从客户那里得到什么?
我们经常需要对客户结构执行一些操作。例如,根据客户的姓和名构造客户的全名:
Fullname = customer。FirstName +”“+ customer.LastName;
每次我们需要全名时编写这段代码,要么导致代码重复(并且很可能不一致),要么导致函数与其数据分离,可能很难找到。
而是定义一个类
相反,我们可以定义一个类为了我们的客户!这样做将带来以下好处:
使用customer类的函数只需要在参数块中进行一行验证——required类。验证行告诉您确切的输入是什么,您可以立即点击Ctrl + D转到类定义。它在调用代码和类之间形成了一个明确的契约。
属性块确切地告诉您哪些属性所有该类的对象将具有。每个属性的验证明确了每个属性将包含什么,它可以设置默认值,并保证类的所有对象都是有效的。
可以添加依赖属性来为您提供派生信息,而不必查看对象的内部(你好封装!);告诉对象你想要它做什么,不要要求单独的数据。与类相关的其他功能可以作为方法添加。
让你的类使用数组
自定义类真正开始发光时,你使它们数组兼容。而不是一个客户或一个Order,您可以拥有一个客户或订单数组,并一次性对它们执行操作。这种原生数组处理是MATLAB的独特特性之一,它消除了对“集合”对象的需求,就像你可能在C中拥有的那样。
我几乎总是添加一个基于数组的方法是表格.表格将对象数组转换为标准MATLAB表格.它允许您轻松地查看对象数组的全部内容,并可能将数据写入场上供展示或到电子表格作报告之用。
那么,为什么要这么麻烦地创建一个自定义类,只是为了把它转换回泛型数据类型呢?现在最关键的区别是桌子派生的从处理所有验证和计算的自定义类;桌子不是真理的来源。
代码示例
下面是示例代码,展示了客户在MATLAB中实现为类时的样子:
- 属性名是固定的,始终存在,并且不能在运行时更改。
- 数据类型和大小是固定的,类型转换在可能的情况下自动执行(例如字符到字符串)。
- 电子邮件在更改时进行验证。
- 的FullName依赖属性使调用代码可以直接访问它实际需要的内容。
- 的表格方法使我们能够轻松地可视化客户数组的内容以及要在应用程序之外使用的数据。
classdef客户属性FirstName (1,1) string LastName (1,1) string Email (1,1) string {mustBeValidEmail} =“undefined@domain.com”结束属性(Dependent,SetAccess = private) FullName(1,1)字符串结束方法函数客户(第一个,最后一个,电子邮件)FirstName =第一个;cust。LastName = last;cust。Email =电子邮件;结束函数str = get.FullName(客户)str =客户。FirstName +”“+ customer.LastName;结束函数TBL =表(顾客)参数顾客(1,:)顾客结束fn = [customers.FirstName]';ln = [customers.LastName]';email = [customers.Email]';TBL = table(fn,ln,email,“VariableNames”, (“FirstName”“姓”“电子邮件”]);结束结束结束函数mustBeValidEmail(value) anyLetterOrNum = alphanumericpattern ();pat = anyLetterOrNum +“@”+ anyLetterOrNum +“。”+ anyLetterOrNum;断言(匹配(价值,帕特),“顾客:InvalidEmail”,“无效的电子邮件”)结束
下面是我们如何使用它:
c(1) =客户(“米奇”,“码头工人”,“mitch@foo.com”) c(2) =客户(“拉克兰”,“莫顿”,“lachlan@bah.com”);c(3) =客户(“Rigoberto”,“巨蜥”,“rigo@uran.com”);表(c)
c =客户与属性:FirstName:“Mitch”LastName:“Docker”Email:“mitch@foo.com”FullName:“Mitch Docker”ans = 3×3表FirstName LastName Email ___________ ________ _________________“Mitch”“Docker”“mitch@foo.com”“Lachlan”“Morton”“lachlan@bah.com”“Rigoberto”“Uran”“rigo@uran.com”
我们可以验证输入sendEmail函数使用简单的参数块:
函数bodyText sendEmail(客户)参数customer (1,1) customer bodyText(1,1)字符串结束%其他代码…结束
什么时候应该定义一个自定义类?
您可能想知道在什么情况下应该努力创建自定义类。就像决定从脚本到函数,或从函数到类一样,这是当您达到当前实现所能做的极限时。如果你发现:
- 很难理解数据结构中的内容。
- 你在验证方面有问题。
- 与数据密切相关的代码被重复、分散或不一致。
现在是时候考虑自定义类了。
评论
要发表评论,请点击此处登录到您的MathWorks帐户或创建一个新帐户。