7个良好的Laravel编程习惯,帮助你减少代码中的Bug,会增加它们的复杂性,随时增加出现bug的可能性。可能在客户会议之前几分钟,或者我们可以在周末去电影院时远离键盘。为了防止那些可怕的情况,让我们通过以下七个技巧编写更好的代码:1.为变量、函数、参数和方法赋予描述性名称:代码编写一次,但会被其他开发人员阅读,而您阅读和解释多次。所以花一些额外的时间来命名这个新类或方法是值得的,这样它的名字就可以揭示它的真实意图或内容。让我们比较一下这两行。哪一个更容易理解?让我们比较一下这两行。哪一个更容易理解?$evnt->add($req->q);$event->addTickets($request->quantity);第一行输入错误,add方法不知道添加了什么,$req这个变量不够明确,很难理解q指的是数量。另一方面,即使对于非开发人员来说,第二个示例也很容易理解。2.使用像PSR-2这样的PHP标准永远不要低估以有序和一致的方式编写代码的重要性,因为这将使您更快地发现问题。考虑以下两个示例:publicfunctionaddTickets($quantity){foreach(range(1,$quantity)as$i){$code=Code::generate();}$this->tickets()->create(['code'=>$code,]);}publicfunctionaddTickets($quantity){foreach(range(1,$quantity)as$i){$code=Code::generate();}$this->tickets()->create(['code'=>$code,]);}两个代码块都有相同的错误:两个代码块只创建了一张票,而它们应该创建N。但是在哪个代码中阻止你更快地发现问题吗?现在想象一下处理复杂的、格式错误的代码的后果。3.减少临时变量的数量虽然我们在第一章算法中学习了如何声明和使用临时变量,但它们仍然使代码难以阅读和维护。考虑以下示例:$contact=array();$contact['firstname']=$user->first_name;$contact['surname']=$user->last_name;$contact['id']=$user->id;$contact_emails=array();$contact_email=array();$contact_email['email']=$user->email;$contact_emails[]=$contact_email;$contact['emails']=$contact_emails;$this->create('contact',$contact);$contact=['id'=>$user->id,'firstname'=>$user->first_name,'surname'=>$user->last_name,'emails'=>[['email'=>$user->email,],],];$this->create('contact',$contact);哪个例子更容易理解?顺便说一句,使用等号是个坏习惯。这不仅违反了PSR-2,还使代码无法维护。所以,回到我们的第二个例子,这个例子可以通过删除代码变量并将其内联写入来优化:publicfunctionaddTickets($quantity){foreach(range(1,$quantity)as$i){$this->tickets()->create(['code'=>Code::generate(6),]);然而,在某些情况下,使用局部变量可以提高代码的可读性,例如:functioncalculateCode($price,$quantity,$deliveryCost){$subtotal=$price*$quantity;如果($小计<30){$小计+=$deliveryCost;}return$subtotal;}可能比下面的Clear更昂贵:create('contact',$user->getContactInfo());面向对象编程要求我们将数据和函数聚集在一个地方(类)。我们将在包含所有用户信息的(用户模型)中组装一个包含联系信息的数组。再看一个例子$subtotal=$item->price*$quantity;$subtotal=$this->addDeliveryCost($subtotal);addDeliveryCost方法将返回一个运费金额,但前提是该金额不超过设置的阀值,否则将返回原始金额。现在让我们删除局部变量并内联代码:return$this->addDeliveryCost($price*$quantity);声明和使用许多小方法是减少代码中临时变量使用的好方法。6.默认使用简单的解决方案许多教程承诺你会写出更好的代码,但最终却使代码过于复杂。如果您使用的是Laravel和Eloquent,这些教程会告诉您将以下代码放在控制器中是错误的://SomewhereinUserController.phpUser::create(['name'=>$request->name,'email'=>$request->email,'password'=>bcrypt($request->password),]);你应该这样写://在UserController.php的某处$this->commandTransport->handleCommand(newUserCreationCommand(newUserNameField($request->name),newUserEmailField($request->email),newUserPasswordField(bcrypt($请求->密码)),));在UserCreationCommandHandler类中,同样不能创建用户,因为违反了SOLID原则。你应该使用repository:classUserCreationCommandHandler{//...publicfunctionhandle(UserCreationCommand$command){$this->userRepository->create($command->name,$command->email,$command->password,);}}最后,在UserEloquentRepository类中,您将最终调用User::create:classUserEloquentRepositoryimplementsUserRepository{//...publicfunctioncreate(UserNameField$name,UserEmailField$email,UserPasswordField$password){returnUser::创建(['name'=>$name->getValue(),'email'=>$email->getValue(),'password'=>bcrypt($password->getValue()),]);}}一段时间后,客户端要求您向User模型添加另一个字段。哪个更简单?哪种解决方案更容易出现错误(可能您忘记将字段从一种方法传递到另一种方法)。此外,您是否注意到bcrypt在示例2中被调用了两次?所以第二个例子有一个错误。不幸的是,某些接口和类不会阻止您犯错误。因此,您需要仔细测试代码。谈到测试代码:7.编写自动化测试。会计师使用一种称为“复式簿记”的方法来记账。这种方法要求他们将所有交易记录两次。编写单元测试需要我们编写代码两次,一次定义每个测试:functiontest_order_without_delivery_cost(){$order=newOrder;$order->addItem(newItem(['price'=>20]),5);$预期总数=20*5;$this->assertSame($expectedTotal,$order->getTotal());}functiontest_order_with_delivery_cost(){$order=newOrder;$order->addItem(newItem(['price'=>20]),1);$expectedTotal=20+DELIVERY_COST;$this->assertSame($expectedTotal,$order->getTotal());}执行第二段代码(这个艰巨的任务就交给你了)。许多开发人员抱怨这种做法,因为它迫使我们“双重工作”,但通过将代码编写两次,我们可以减少以相同方式犯同样错误的机会(如果我们犯了两个不同的错误,测试可能会失败)。这就是为什么实施一些单元测试的项目经常会出现需要数小时调试的小错误。
