从过程函数到OOP类(一种具体情况)
仍在学习 OOP,并试图改变我对程序生活方式的看法。我在重构时发现了很多优点,但现在我陷入了一个范式:
我正在重构一个购物车。当结帐时,在我的旧 php 脚本中,我的函数文件中有一个函数,该函数将用户带到不同的付款方式(PayPal、卡、汇款等),每种方式都有不同的操作、值、功能, url 等。
那么,我可以将“付款方式”视为一个类吗?
在我的旧脚本中,结账是线性的,一个又一个动作,但现在我想重用付款类进行预订、延期付款、订阅等,而不是跟随人类买家的点击。我认为这就是 OOP 的闪光点,不是吗?
我认为该类可以具有总计、小计、折扣、tpv 选择、结果、错误消息等属性...但是...其中一些属性已经是我的篮子类的一部分。
以及如何使用它?从外部调用其函数并发送大量参数(例如信用卡要求)?或者强制类在首选项文件中外部获取这些值?
每种付款方式都有一个不同的类,或者包含所有付款方式的一个大类...
我真的看不到范例...但我几乎确定它就在那里:-)
Still learning OOP, and trying to change my perspective from procedural way of life. I've found a lot of advantages when refactoring, but now I am stuck in a paradigm:
I am refactoring a shopping cart. When it goes to checkout, in my old php scripts I had a function in my functions file that takes the user to the different payment methods (PayPal, cards, money transfers, etc), each of them with different acctions, values, functions, url, etc.
So, can I see a "payment method" as a Class?
In my old scripts the checkout was lineal, action after action, but now I want to reuse the payment Class for reservations, deferred payments, subscriptions, and so on, not following the clicks of a human buyer. I think this is when OOP shines, isn´t it?
I think the Class can have Attributes like total, subtotal, discount, tpv selection, result, error messages... but... some of them are already part of my Basket class.
And how can use it? calling its functions from outside and sending a lot of parameters such as credit card requirements? or forcing the Class to obtain those values outside, in the preferences file?
A different class for each payment method, or a big class with all of them...
Really I can't see the paradigm... but I am almost sure it's there :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这个问题在某些方面是含糊的,因此这个答案中的某些部分也必然是含糊的。
在纯 OOP 中,一切都是类或方法。 Payment Method 类是有意义的,特别是当存在不同的支付方法时。
将支付方式归结为其基本要素和行为。问自己这样的问题:货币数量真的是某人支付方式的一部分,还是支付金额的一部分? (回答这个具体问题:它们是付款的一部分,而不是付款方式)进行付款时,将需要付款信息,但可以将其传递给需要它的任何方法(可能在 Payment 对象中,它代表从买家发送给卖家的金额,或者在 Order 对象中,或者 Order 对象可以实现 Payment 接口,尽管最后一个不会 对现实世界进行建模 单射式 )。
如果付款要求是付款方式的一部分,那么它们应该是付款方式的属性。至于支付方式对象是如何初始化的,可以使用依赖注入技术(其中一个单独的类负责确定哪种支付方式(以及其他特定类别)应该参与交易并进行设置)可以应用,尽管它并不总是最佳选择。您还可以有一个控制器来响应用户通过读取配置数据并创建支付方法对象、将所述数据传递给支付方法来执行的操作(即选择支付方法)。
有几种有效的方法可以使用支付方法对象。任何时候,一个动作涉及多个对象,而其中一个对象不是明确的参与者(即应该执行操作),您可以使用自由函数(即非方法函数)来调用适当对象的必要方法。如果函数的行为根据多个对象的运行时类型而变化,您可以使用多方法< /a> (如果可能的话;没有多少语言本身支持多种方法,尽管您可以使用某些模式在许多语言中模拟它,例如 双重调度)。其他可能性包括让控制器作为主要参与者。
在实现设计时可以提供帮助的一个概念是制定的访问规则在功能编程中显式:对象可以访问它们创建的、已知创建的(即传递给它们的构造函数)或引入的其他对象。这些规则为依赖注入、模型-视图-控制器 (MVC) 等技术提供了信息。
介于两者之间。所有支付方法通用的任何内容(例如操作 URL)都应该放在基类中。如果付款方法需要覆盖常见行为或需要其他方法不需要的字段,请对基本付款方法进行子类化。为了保持一致性,您可以扩展所有付款方式的基类,尽管某些子类可能不会覆盖任何内容。
The question is vague at parts, so some of this answer is likewise necessarily vague.
In pure OOP, everything is a class or a method. A Payment Method class would make sense, especially as there are distinct payment methods.
Boil payment methods down to their essential constituents and behaviors. Ask yourself questions like: are monetary quantities really a part of how someone pays, or are they a part of what is being paid? (Answer to this specific question: they are part of a payment, not a payment method) When a payment is made, payment info will be needed, but it can be passed to whichever methods need it (perhaps in a Payment object, which represents a monetary amount sent from a buyer to a seller, or in an Order object, or an Order object could implement a Payment interface, though the last wouldn't model the real world injectively).
If payment requirements are part of payment methods, they should be properties of payment methods. As for how payment method objects are initialized, the dependency injection technique (where a separate class is responsible for determining which payment method, among other specific classes, should be involved in a transaction and set them up) could be applied, though it isn't always the best choice. You could also have a controller that responds to an action from the user (i.e. selecting a payment method) by reading the configuration data and creating the payment method object, passing said data to the payment method.
There are a couple valid approaches to using a payment method object. Any time an action involves multiple objects and one isn't a clear actor (i.e. the one that should perform the action), you could use a free function (i.e. a non-method function) that calls the necessary methods of the appropriate objects. If behavior of the function varies depending on the run-time types of multiple objects, you'd use multi-methods (if possible; not many languages support multi-methods natively, though you can simulate it in many languages with certain patterns, such as double dispatch). Other possibilities include having a controller as the primary actor.
One concept that can help when implementing designs are the access rules made explicit in capabilities programming: objects can access other objects that they create, are created knowing (i.e. passed to their constructor) or are introduced to. These rules inform techniques such as dependency injection, Model-View-Controller (MVC) and so on.
Somewhere in between. Anything that is common to all payment methods (such as an action URL) should go in a base class. If a payment method needs to override the common behavior or needs a field that other methods don't, subclass the base payment method. For consistency's sake, you could extend the base class for all payment methods, though some subclasses might not override anything.
根据您所描述的内容,我认为适合的 OOP 架构将遵循以下原则:
ShoppingCart 实际上只需要了解它包含的购买和一组可用的 PaymentMethods。您可以要求每个 PaymentMethod 在结账页面上选择付款方式时显示名称和徽标。您还可以要求每个 PaymentMethod 有一个方法来显示必要的 GUI,以提供处理一组购买所需的任何信息。
我是根据我的架构方式来编写这篇文章的,尽管作为一名主要是 C++ 的游戏程序员,所以您可能需要适应我的一些术语和方法来进行 Web 开发。
不要将您的程序性思维方式视为问题,只需认识到某些问题最好用不同的范式来解决。在这种情况下,我认为面向对象范式非常适合此类问题。并不是所有的事情都必须是 OOP,也不是所有的事情都必须是过程的。
Based on what you're describing, an OOP architecture that I think would fit would be along these lines
The ShoppingCart really only needs needs to know about the Purchases it contains and a set of PaymentMethods available to it. You could require each PaymentMethod to have a name and logo to be displayed when selecting payment methods on the checkout page. You could also require each PaymentMethod to have a method that displays the GUI necessary to provide it whatever information it requires in order to process the set of Purchases.
I'm writing this based on how I'd architect it, as a primarily C++ game programmer though, so you may have to adapt some of my terminology and methodologies for web development.
Don't consider your procedural way of thinking as a problem, just recognize that certain problems are best solved with different paradigms. In this case, I think the object-oriented paradigm is well suited for this kind of problem. Not everything has to be OOP, not everything has to be procedural though.