"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:My procedural-programmer's mind has me thinking that last bit supports as much functionality as the rest, and is quite a bit simpler. The author, however, defends his OOP approach with the usual points (modularity, isolation of function, and so on). In those cases where the other classes besides BankAccount retain some state, I might see his point. But, my question is, what advantages accrue to the use of additional classes that retain, as their only internal state, a reference to an object of a different class when those additional classes will only perform their method's operations in ways that affect that object? How/why is that any better than each of those methods simply being methods of that object in the first place?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Campbell Ritchie wrote:A teller can access many accounts, so I think it does merit a separate existence as a class in its own right.
"Il y a peu de choses qui me soient impossibles..."
Winston Gutkowski wrote:Well first off, I would say that a simple class doesn't support any notion of subtyping of accounts (eg, Savings, Investment, Current etc.); and secondly IMO your class supports the model, rather than the actuality, of an Account, which of necessity involves not only transactions, but their persistence (models are generally only interested in current state, not history).
I do reckon that he's missed an important transaction though: a transfer. Now you could argue that it's simply a withdrawal from one account accompanied by a deposit to another, but it must be atomic, and it may also have associated charges or rules, so I'd certainly have one.
My "first cut".![]()
Winston
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:One could, however, imagine a Transaction object that would be a collection of cashflows...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:One could, however, imagine a Transaction object that would be a collection of cashflows...
Yes, but to my mind that would probably be a subtype. In the real world, you may have other transactions like change of name/address that have their own foibles.
For me, a 'bank transaction' is very similar to a database transaction - ie, a "unit of work" - but geared to the sorts of things a bank needs to do; and probably also governed by all sorts of rules, including imposed ones, like how long you have to keep records for.
It's also worth remembering that, in ledger terms, all 'value' transactions are actually transfers; however, that's about the extent of my knowledge when it comes to DEB systems.![]()
Winston
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:Is there any advantage to that over putting the transfer code directly into the account object?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:A Transaction, on the other hand, is much closer to a business process; and is likely to have rules (charges, history retention, etc.) that have to do with what's being done rather than relating to a specific Account.
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:...but that this topic (objects that do things to other objects, more than they are for the purpose of storing data themselves), seem to get names that are agent nouns. That is, a BankAccount is a sack of money. Someone must take the intiative to move money from one BankAccount to another. If the BankAccount is capable of moving its own money, it might implement a Transferable interface. But, if not, someone (or something) must move that money instead. Hence, if an object will tranfer (a verb) money, that object might be called a Transferor (an agent noun).
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:So, fellows, am I on the right track here? Does this look like OOP, or am I just bein' another Brooklyn rube and fakin' it? Campbell? Winston?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Well, there are worse things to be accused of, I suppose.Winston Gutkowski wrote:I think perhaps you're overthinking it...
Good reminder. I mulled this over for the last few days, avoiding the keyboard, sketching stuff out on paper instead.and, as you well know, the best thing to do in those cases is to StopCoding.
![]()
Heh. I'm a lawyer, so words like "Transferor" slip into my code sometimes. It's a legitimate word, but I agree it's a bit awkward. My purpose in using it was not so much to propose it as the ideal choice, but rather to try out my "agent noun" idea for classes that exist more to provide their methods than to store data in their instances.For a start, banks are required to keep records, and a Transaction is that record ('fraid I don't like Transferor too much - it seems like one of those 'made up' words that don't have much meaning outside your bank). Secondly, while you, as an 'owner', may own the money in your box, you don't own the box itself; the bank does. The bank also provides security for each owner; otherwise, why wouldn't they just keep their money under their mattress?
Okay, I think I am getting somewhere with this idea of a Transaction (which certainly includes data dinstinct from what would be in a BankAccount), and an actor. In my attempts above, my Transferor was the actor. So let me come full-circle to a more abstract question (and not write any code). What I am wondering is if the original case study made more sense than I thought it did, by locating certain methods in a class that only operated on another class. That is, the only instance variable in the author's TellerAccountAccessor (what maybe we would really just call a "Teller" here), was a reference to a BankAcount. My puzzlement is/was over why that's any better than just locating the TellerAccountAccessor's methods in the BankAccount class in the first place.I'd say that the "actor", in this case, is actually the Teller, who is the Bank's proxy for the Account holder, or Owner. Their sole job is to see that procedures are followed, and that the real actor (the Owner) is actually the one who requested a specific Transaction to take place.
Before the days of ATMs (and especially back in the bad old days before interstate banking in the US), these procedures could involve promissory notes, telephone calls, or even bonds to make sure that transactions were valid and secure - especially if the Owner couldn't go to their own branch - but, at the end of the day, the Transaction is simply the record - or if you prefer, the authorization - for a change to occur.
Now, in Banking terms that might mean that a Transaction has to have an actor, but not that it is the actor.
It's worth more than that to me. Thanks.My 2 cents.
Winston
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:That is, suppose I have an object that, say, stores an image (a raster full of pixels, I mean). Now suppose I am writing dozens, maybe hundreds, of short methods that process that picture in some way. Maybe one of them inverts it to a negative of itself. Another reflects it like in a mirror...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
No, no! That's my point: the Image is the thing to be processed, but the processor is a big set of methods. Whether one puts them in the Image object (which, I grant, would be distasteful) or the Photoshop object, it seems they do all belong together. I keep reading that, if one's class is over 200 (or 500, or 1000; take your pick) lines long, then one's class is too long. Granted, these are always qualified as "guidelines," but the people offering them tend to go on from there as though they'd never said that, and act like any class over 200/500/1000 lines has just got to be badly designed. I'm working on an image-processing application that just doesn't have that much in the way of state, but it does have tonnes of methods that all do something to a raster full of pixels (a "Bitmap," just as you said).Winston Gutkowski wrote:
Stevens Miller wrote:That is, suppose I have an object that, say, stores an image (a raster full of pixels, I mean). Now suppose I am writing dozens, maybe hundreds, of short methods that process that picture in some way. Maybe one of them inverts it to a negative of itself. Another reflects it like in a mirror...
I think you're confusing the Image with Photoshop.![]()
All the other stuff you mentioned strikes me as part of your Photoshop class (or classes); and considering the multitude of filters available for image manipulation (there's at least a dozen for resizing alone), yes, it's quite possible that you will have classes that contain piles of methods.
Or, more likely, they'll be part of some image manipulation library - don't re-invent the wheel.
![]()
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:Thus, I am kind of baffled about all this. Is passing a reference in a constructor call just a way to help move code out of the referenced object? If so, is that a commonly accepted practice?
That is, is it good practice to create a class solely for the purpose of providing a tidy place to store methods, when those methods will not operate on any instance variables of that class, but, instead, operate on another object entirely? That seems like a dodge, to me, serving the same function that libraries of functions perform in procedural languages.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Stevens Miller wrote:It's the difference between "class" and "classes" that has me going 'round in mental circles on this. Why would I put one method into one class, and another into another class, when both are of the form "public void processImageXXX(BuffferedImage image)"? Just because that keeps my classes smaller?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Stevens Miller wrote:I keep reading that, if one's class is over 200 (or 500, or 1000; take your pick) lines long, then one's class is too long. Granted, these are always qualified as "guidelines," but the people offering them tend to go on from there as though they'd never said that, and act like any class over 200/500/1000 lines has just got to be badly designed.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:It's the difference between "class" and "classes" that has me going 'round in mental circles on this. Why would I put one method into one class, and another into another class, when both are of the form "public void processImageXXX(BuffferedImage image)"? Just because that keeps my classes smaller?
No, it's to help define them. You might have a Sharpener class, or a Resizer class, or an Effects class (I'm just going by what I've seen in PS and Gimp you understand; I've really no idea how I would write - or group - them), and they could easily be interfaces rather than classes, so that designers are free to implement them any way they see fit.
And the fact that they act on an Image? Well, my presumption (although again, I'm no expert in this stuff) is that an Image might be in bitmap or vector-graphics form; and that the internals for each of those types would be drastically different, even though the facade they present to the world (ie, the "things" you can do to them) is the same.
Winston
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:Short version is that I am having a hard time seeing any difference between stateless static methods and a library of functions.
But it's comforting to see that some of the indicia I expect of contexts calling for large classes with many methods (most specifically, that they have no state) do appear in actual practice.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:Short version is that I am having a hard time seeing any difference between stateless static methods and a library of functions.
Short answer is: they don't. But in OO, truly stateless classes are quite rare - and usually created to mimic exactly what you describe - including, as you said, java.lang.Math. It might be worth noting though that Math.random() has been superceded by (and the method actually rewritten to use) java.util.Random, which is a purpose-built random number generator class, and IMO much more useful.
But it's comforting to see that some of the indicia I expect of contexts calling for large classes with many methods (most specifically, that they have no state) do appear in actual practice.
As I say, it does happen, but not as often as I suspect you think.
A lot of the methods in String, for example, might look stateless; but that's because String is immutable.
And as for your Photoshop methods, it seems far more flexible to me for its library to be made up of a bunch of interfaces which anyone who thinks they have "better mousetrap" can implement, rather than a bunch of static classes - ie, the same paradigm that's used for JDBC.
However, we seem to have strayed somewhat from the original brief...
![]()
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:If I may, let me continue for a moment with the PhotoShop situation (since I understand that better and it's closer to what I'm doing). Suppose, for example, that I have a number of raster images I want to resize.
Uh... am I evenly remotely getting it here?
Feel free to e-mail me any American legal questions you might have...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Today you are you, that is turer than true. There is no one alive who is youer than you! - Seuss. Tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|