我想问你关于Laravel中的可靠原则,特别是关于接口分离原则。
假设我们有一个用户可以发送订单的应用程序。但对于每个用户,我们都有不同的发送订单的方式。例如,用户one -通过电子邮件发送订单。用户2-通过上传到ftp的xml发送订单。按照这种思路,我们可以在php中创建接口:
然后,And为每个特定用户实现它。但在Laravel中,我们只有一个类User。假设用户具有user类型的属性,我们可以从中找到sendOrder类型。在Laravel中做这件事最好的方法是什么?也许是一个开关/if来查找并返回正确的实现,或者有更好的方法?
发布于 2019-02-04 14:25:45
这感觉像是策略模式的一个很好的用例。在您的示例中,用户可以有多种发送订单的方式。换句话说,多个策略。这也是考虑将订单逻辑添加到服务层的好时机。
诚然,你的问题有点含糊,但我会试着举一个例子,说明我可能如何完成这项工作。因此,假设您的App\User
模型将实现您的接口ISendOrder
。
您的OrderService
的一个非常小的示例如下所示:
这一步纯粹是可选的,但我可能会将订单发送逻辑封装在一个特征中。你的模型会看起来干净多了。此外,您还可以轻松地将此逻辑添加到将来可能发送订单的任何其他models
中。
您的特征将如下所示:
这是一个很小的例子,用来说明你是如何做到这一点的。
发布于 2019-02-04 14:26:36
注意主观的问题,比如“什么是最好的方式……”,这个网站是专门针对细节的。但是,关于你的问题,有一些事情可能会有所帮助。
单一响应性:一个类应该只有一个改变的理由。如果您遇到多个类,请将其重构为单独的类。也就是说,不要将“用户”和“消息驱动”的概念融合在同一个类中。
Open Closed:类应该是开放的,可以使用子类进行扩展或重写,但不能在of本身中修改现有方法的输入或输出。也就是说,不要从可能已经在使用该类的东西中拉出地毯。功能测试是确保重构不会意外做到这一点的好方法。
Liskov替换:兄弟类应该是可互换的。你谈到有不同种类的变速器驱动程序。电子邮件与FTP。您的EmailDriver和FtpDriver类都应该实现一个定义send()
方法的接口。因此,任何使用其中一种方法的东西也应该能够处理另一种方法。您的Adapter类同时使用要与之通信的User
和定义通信机制的Driver
,因此不必关心细节。
界面隔离:简而言之,让你的界面保持苗条。如果一个类愿意的话,它总是可以实现多个。如果单个接口要求对象支持太多,而不是实际需要的,可能会导致不必要的复杂性。
依赖倒置:这种方式与Liskov替换密切相关。高级类应该依赖于接口而不是具体的类,以便在需要时以最少的重构更容易地交换组件。
Laravel的Service Container做了很多这方面的工作。服务提供者将具体类绑定到抽象。通常,这些抽象是字符串接口名称,但它们实际上可以是任何字符串。这在一定程度上是门面的工作原理。
Laravel实例化新对象的方式应该总是依赖注入。通过键入提示(如果适用)或使用app()
帮助器函数。
当你请求Laravel以这种方式实例化一个对象时,你所做的就是让容器有机会用提供者中定义的类来交换你所请求的类。
不过,回到你的具体问题上,当涉及到指示你的代码为谁利用哪个传输驱动程序时,如果没有更多的信息,我不能肯定,这只是一个观点,但你可能想看看工厂Pattern(https://en.wikipedia.org/wiki/Factory_(object-oriented_programming%29)是否适合你的情况。
发布于 2021-02-27 15:50:38
我写这篇文章是希望能澄清一些人关于接口隔离的概念。
我认为,@mozammil为Laravel的具体情况提供了最好的答案。
但是,如果您对这种接口隔离有清晰的概念,那么在任何编程案例中使用它都同样简单- Java
、PHP
、C#
、Python
或任何编程语言。
接口隔离:
客户端/用户不应该依赖于他们不能使用的接口,而不是将这些接口分离为几个接口。
例如,如果我们这样做,就可以检查一切是否正确。
BankPayment
类使用两个与其相关且必要的函数。但是,如果有任何新的东西到来。喜欢需要添加贷款计算和检查。
看看这个,对于LoanPayment
类来说一切都很好,但是对于BankPayment
类来说,新的两个函数是不必要的,应该在另一个接口中分离出来。
这就是SOLID中的接口隔离原则。
要获得关于SOLID principles的完整概念和现实生活中的实现,您可以查看以下内容- https://devsenv.com/tutorials/solid-principle-in-depth-with-practical-example
https://stackoverflow.com/questions/54517534
复制相似问题