3 ms·
How is it more testable than the second option? previous = account.balance credit_amount = rand 1000 account.credit_dollars credit_amount assert_equal
by bonzoesc 14y ago
How is it more testable than the second option?
previous = account.balance
credit_amount = rand 1000
account.credit_dollars credit_amount
assert_equal previous + credit_amount, account.balance
And more importantly, how is option 3 a better idea for reuse?
- benjaminwootton 14y agoWith even a dash of business logic on the transaction object I think 3 is better code. It's more testable because we can test the concept of a transaction rather than the net result of incrementing the account balance - e.g. test for a business rule to ensure that we can never have a transaction with a negative credit. It promotes single responsibility because logic pertaining to the transaction can be pushed back onto the transaction object where it is defined once and where it more naturally sits - e.g. validate the transaction or render yourself for printing. It promotes reuse because the transaction object could possibly be used in another context far removed from this particular scenario - e.g. any logic for validating or rendering the object would sit within the account object otherwise. It makes sense to bring it out where we could potentially reuse it later. This is just object orientation 101, and it preaches the flexibility that the OP is against. Good OO code is code that is flexible and contains a certain degree of abstractions by design.
- bonzoesc 14y agoBut you've lost the abstraction of crediting somebody! Now you have to know about transactions to give out that credit, and while it might be more flexible, you've lost your encapsulation and abstraction. Option three would be suitable for the implementation of option two, I'll give you that, but if I'm designing an admin control panel I want to bind a control to credit an account, not to create a transaction to credit something and have an account process that transaction.
- rprasad 14y agoThe point of using a standardized transaction object is that you can than track/manage all such transactions using roughly the same logic. Consider: crediting an account is merely a negative transaction, so there is no point in creating extra overhead or code to manage crediting transactions separately. This would allow you, for example, to track and handle all transactions, including crediting transactions, using the same code base, with special transaction-type-specific issues dealt with by the transaction-type object.