Java Forum / General / November 2005
Accessing an invoking class's getters?
Rhino - 10 Nov 2005 15:11 GMT Can someone remind me of the idiom for accessing the getters for a class that invoked another class?
For example, let's say I have instantiated an instance of class Alpha and it is called alpha. My alpha instance sets some class variables, say foo and bar, and invokes a class Beta, creating an instance called beta. Now, beta, the instance of class Beta, needs to see alpha's variables foo and bar. What is the idiom for seeing those values?
public class Alpha {
String foo; int bar;
public Alpha() {
setFoo("Dog"); setBar(1);
}
public void actionPerformed() {
Beta beta = new Beta();
}
public void setFoo(String myFoo) {
foo = myFoo; }
public void setBar(int myBar) {
bar = myBar; }
public String getFoo() {
return foo; }
public int getBar() {
return bar; } } //end Alpha
public class Beta {
String foo; int bar;
public Beta() {
// How do I get the values of foo and bar that were set in the invoking instance? this.foo = ??.getFoo(); this.bar = ??.getBar(); } //end Beta()
} //end Beta
I *think* I had to do this at some point in the fairly distant past but I can't find an example in my source libraries. I don't know the exact terminology for what I'm trying to do so a Google search or looking through an FAQ gets tricky. I'm hoping someone can remind me of this idiom.
By the way, is this - using the invoking class's getters - considered a bad thing to do in OO terms?
I'm trying to reduce the number of parameters that Alpha has to pass to Beta when Beta is instantiated and, since Alpha has already set those values, it seems reasonable to simply ask alpha what values those variables have. One alternative, of course, is that I could simply pass those variables to Beta when I instantiate it but I'm concerned that I'm passing too many parameters when I do everything that way; some of my "Betas" are getting almost a dozen parameters passed to them. I'm thinking of passing important values as parameters and lesser values via the idiom I am asking about.
Any guidance you have to offer on either the specific idiom I've asked about or the general issue of the best techniques for passing parameters to a constructor would be greatly appreciated.
 Signature Rhino
Bjorn Abelli - 10 Nov 2005 15:31 GMT "Rhino" wrote...
> Can someone remind me of the idiom for accessing the > getters for a class > that invoked another class?
> public class Alpha { ...
public void actionPerformed() {
// Beta beta = new Beta(); Beta beta = new Beta(this);
}
-------------------------
public class Beta {
... public Beta(Alpha a) {
this.foo = a.getFoo(); this.bar = a.getBar(); }
}
...is one way of doing it...
If you need access to the instance of Alpha elsewhere in the Beta instance, you could also keep the reference...
-------------------------
public class Beta {
...
Alpha a;
public Beta(Alpha a) { this.a = a; this.foo = a.getFoo(); this.bar = a.getBar(); }
}
// Bjorn A
Rhino - 10 Nov 2005 15:40 GMT > "Rhino" wrote... > [quoted text clipped - 48 lines] > > // Bjorn A I finally found an example that did exactly what you describe about 10 minutes after I posted my question. I knew I'd done it before at some point ;-)
So, this is a perfectly valid thing to do, right?
I guess I'm still a bit worried about the bigger design question though. Is it better to pass a list of values from Alpha to Beta, even a fairly long list of values, as discrete parameters in the method constructor signature itself? Or is it better to pass a single reference to the invoking class and then use getters from the invoking class to determine the different values needed?
Also, is it bad form to do a mix of the two techniques, i.e. to pass "important" values as parameters to the constructor and obtain "lesser" values from a reference to the invoking class?
A rule of thumb to help me decide the appropriate technique would be very helpful.
Can anyone suggest such a rule?
Rhino
Bjorn Abelli - 10 Nov 2005 16:26 GMT "Rhino" wrote...
> "Bjorn Abelli" wrote...
>> public void actionPerformed() { >> [quoted text clipped - 8 lines] >> } >> }
> So, this is a perfectly valid thing to do, right? Yes.
> I guess I'm still a bit worried about the bigger design > question though. Is it better to pass a list of values > from Alpha to Beta, even a fairly long list of values, > as discrete parameters in the method constructor signature > itself? If there's no other relation between an instance of an Alpha and a Beta, this would be the prefered method, as you then decouple the dependence to Alpha from a Betas point of view.
If there's a need to have a very long list of values, there are patterns to deal with this.
One is to encapsulate the needed values into one single object, and to pass that instead...
> Or is it better to pass a single reference to the invoking > class and then use getters from the invoking class to > determine the different values needed? If the Beta instance *anyway* have a dependency of some sort towards an instance of Alpha (e.g. if it at some point needs to invoke some method on the Alpha instance), this would be the prefered method, and simplifies much...
> Also, is it bad form to do a mix of the two techniques, > i.e. to pass "important" values as parameters to the > constructor and obtain "lesser" values from a reference > to the invoking class? IMHO I would consider it "ugly", and not thoroughly pondered upon...
// Bjorn A
Rhino - 10 Nov 2005 18:03 GMT > "Rhino" wrote... > > [quoted text clipped - 32 lines] > One is to encapsulate the needed values into one single object, and to pass > that instead... I was starting to think along exactly those lines but wasn't sure if that was good design.
But now that I know it is not bad design to pass an instance of Alpha to a new instance of Beta via it's constructor, my list of parameters is much smaller and much more manageable so I don't think I need to pass the remaining parameters via a single Object.
> > Or is it better to pass a single reference to the invoking > > class and then use getters from the invoking class to [quoted text clipped - 11 lines] > > IMHO I would consider it "ugly", and not thoroughly pondered upon... Let me explain myself a bit better with more concrete parameters.
The Beta in my scenario is actually a preferences dialog for Alpha and should probably be called AlphaPreferences, not Beta. Many of the values AlphaPreferences needs are things that it is sharing with Alpha, such as a logger and a locale. But some of the values that AlphaPreferences needs are to know whether it is modal and what its title should be so that the correct title is placed in its GUI. The logger and locale seem like things that I should be obtaining from the alpha instance that is passed to AlphaPreferences via the 'this' reference. But the modal boolean and the dialog title "feel" different somehow so I am inclined to pass them as explicit separate parameters.
I'm not sure I can explain why the logger and locale are different than the modal boolean and the title though. Maybe it is an unimportant distinction.
For what it's worth, AlphaPreferences subclasses JDialog and shares an interface of constants with Alpha. I don't expect that anyone is ever going to subclass AlphaPreferences or that any other class but Alpha is ever going to instantiate AlphaPreferences. (Maybe I should make AlphaPreferences final to emphasize that; what do you think?)
Should the fact that no class other than Alpha is ever going to instantiate AlphaPreferences and that no one is ever going to subclass AlphaPreferences change anything in how I am going to invoke it?
Rhino
Chris Uppal - 10 Nov 2005 19:45 GMT > The Beta in my scenario is actually a preferences dialog for Alpha and > should probably be called AlphaPreferences, not Beta. Many of the values [quoted text clipped - 10 lines] > the modal boolean and the title though. Maybe it is an unimportant > distinction. One way to think about it is:
The logger and locale are information that the AlphaPreferences needs in order to do its job, but it's not an Alpha's business to know exactly what it needs, only the AlphaPreferences knows that (or should know that). The title and modal-ness, on the other hand, are part of the definition of the job, and should -- must -- be provided explicitly from outside.
Try an analogy: Imagine I happen to visit you, and offer to help out with some redecoration that you are doing. You ask me to hang a picture on a wall. OK, hanging the picture is my job, it's not /my/ responsibility to decide /which/ picture, nor (probably) on which wall -- that is part of the job definition. But once I've been given that info, I'll still have to decide how to hang the picture; if I decide to use a nail and a bit of string, then I'll have to find them (and a hammer, and possibly a chair to stand on). Finding these things is also part of my job, it's not for you to tell me where they are -- although I /may/ decide to come back and ask you "where's a hammer ?" I don't /have/ to. OTOH, you may decide to make that kind of thing part of the job definition too: "If you need anything, come and ask me, please don't bother these other people or go wandering around unattended". You have then set the limits on /where/ I can look for any resources that I may decide I need, but you haven't tried to tell me /what/ resources I should use. If instead you had said, "here, take /this/ hammer, /this/ nail, /this/ length of string, and hang /this/ picture on /that/ wall" I would probably hit you over the head with the hammer -- or possibly the picture ;-)
-- chris
Rhino - 10 Nov 2005 23:41 GMT > > The Beta in my scenario is actually a preferences dialog for Alpha and > > should probably be called AlphaPreferences, not Beta. Many of the values [quoted text clipped - 18 lines] > modal-ness, on the other hand, are part of the definition of the job, and > should -- must -- be provided explicitly from outside. I'm tempted to phrase that as follows: Alpha insists that AlphaPreferences uses a specific name and modal-ness and provides it explicitly but doesn't much care where AlphaPreferences gets a Logger or Locale as long as it gets one. But that doesn't really work either, at least to me. Logger and Locale are getting derived from the instance of Alpha that was passed to AlphaPreferences; that instance is being passed for SOME reason, presumably so that AlphaPreferences can do its thing.
The design aspect here has me confused; if I'm the guy writing the specs for AlphaPreferences, I'd probably say _something_ about where it should get its Locale and Logger. Wouldn't I say that it should use the same Logger and Locale as Alpha, as opposed to using a default that might not be appropriate or prompting the user for his choices of Locale and Logger? I might not say that this information had to be passed via explicit separate parameters and simply leave it up to the developer to decide if he wanted to pass separate parameters or just pass the entire Alpha instance which he could then interrogate for the Logger and Locale. Or maybe pass ALL of the values needed by the constructor in a separate class?
See this is why my head hurts (metaphorically) when I try to decide what I should be doing ;-)
> Try an analogy: Imagine I happen to visit you, and offer to help out with some > redecoration that you are doing. You ask me to hang a picture on a wall. OK, [quoted text clipped - 13 lines] > /that/ wall" I would probably hit you over the head with the hammer -- or > possibly the picture ;-) You're not a trainer by any chance, are you? You certainly have a ready gift for devising good, clear metaphors ;-)
Rhino
Bjorn Abelli - 10 Nov 2005 22:00 GMT "Rhino" wrote...
> The Beta in my scenario is actually a preferences dialog > for Alpha and should probably be called AlphaPreferences, [quoted text clipped - 8 lines] > dialog title "feel" different somehow so I am inclined > to pass them as explicit separate parameters. To me, this rather sounds that you haven't considered that you possibly violate the rule of high cohesion...
To me it now sounds like both Alpha and AlphaPreferences is doing "too much"...
In very small projects, everything can done be within just a few classes, but with just a slightly more complexity in the application, you just "have" to separate the "presentation layer" from the "logic".
I sounds to me that you possibly should solve this by doing just that.
> I'm not sure I can explain why the logger and locale > are different than the modal boolean and the title though. > Maybe it is an unimportant distinction.
> For what it's worth, AlphaPreferences subclasses JDialog and shares an > interface of constants with Alpha. I don't expect that anyone is ever [quoted text clipped - 4 lines] > final > to emphasize that; what do you think?) A totally personal opinion of mine is that I'm a bit allergic to final classes... ;-)
That would inhibit several evolution strategies of an application that otherwise could be possible in the future...
> Should the fact that no class other than Alpha is ever going to > instantiate > AlphaPreferences and that no one is ever going to subclass > AlphaPreferences > change anything in how I am going to invoke it? I think Chris made a point in the difference between the concepts of class and object. If there really is that a specific instance of Alpha controls the behaviour of a specific instance of AlphaPreferences, and that instance of AlphaPreferences is truly depending on some values of that specific instance of Alpha...
...then it possibly isn't something else than different "views" on the *same* object, that it logically isn't different objects...
Maybe you should look over the design to see whether you can separate the actual logic from the GUI, and see what happens...
// Bjorn A
Rhino - 11 Nov 2005 00:03 GMT > "Rhino" wrote... > [quoted text clipped - 13 lines] > To me, this rather sounds that you haven't considered that you possibly > violate the rule of high cohesion... Sorry, I don't know that rule. Can you possibly state it (briefly)?
> To me it now sounds like both Alpha and AlphaPreferences is doing "too > much"... That's possible. I first learned programming and design back in the structured programming days and I probably still think that way more than I think in OO. How can I tell if a class is doing too much? There must be some kind of rule of thumb, like more than 10 methods or more than 20 class variables or more than 500 lines of code....
> In very small projects, everything can done be within just a few classes, > but with just a slightly more complexity in the application, you just "have" > to separate the "presentation layer" from the "logic". > > I sounds to me that you possibly should solve this by doing just that. Perhaps. The existing design "feels" right to me but I don't necessarily have the right instincts. To me, it makes sense that all of the code needed to change the preferences in Alpha be put into a separate class called AlphaPreferences. AlphaPreferences instantiates several smaller classes to do some of its job, like panels to change text preferences or choice box options or images used in Alpha's GUI. There doesn't seem to be much duplication or overlap between Alpha and AlphaPreferences so it feels like the code is organized properly. I'm just struggling with the best ways to get information from one to the other.
> > I'm not sure I can explain why the logger and locale > > are different than the modal boolean and the title though. [quoted text clipped - 11 lines] > A totally personal opinion of mine is that I'm a bit allergic to final > classes... ;-) Fair enough; I just mentioned the 'final' bit on the theory that it's probably a big no-no to omit 'final' if you don't want that class to be extended at some point.
> That would inhibit several evolution strategies of an application that > otherwise could be possible in the future... But I can see that 'final' does prevent extending the class if I do decide to subclass at some point in the future.
> > Should the fact that no class other than Alpha is ever going to > > instantiate [quoted text clipped - 13 lines] > Maybe you should look over the design to see whether you can separate the > actual logic from the GUI, and see what happens... So I should think of rolling the code from AlphaPreferences back into Alpha??
I have to say that "feels" wrong: Alpha and AlphaPreferences each have their own GUIs and, by the nature of preferences, the AlphaPreferences GUI is much more complex than the Alpha GUI. Whereas Alpha's GUI is pretty simple, AlphaPreferences is a JTabbedPane with 7 panes on it where each of those tabs has its own kind of preferences on it. For example, one tab let's you enable or disable features via checkboxes; another tab lets you choose different images to use in Alpha; another tab lets you choose different background Colors for the components shown in Alpha, etc.
My gut hunch says that each GUI should have its own class to control what its doing.
Or have I misunderstood you?
I know it must be hard for you to discuss this without actually seeing any code. My simplifications and generalizations may not be giving you a really good sense of what the code actually does.
Maybe I need to read the MVC theory again to see if I'm putting the right code in the right places. I don't really *THINK* in terms of Models, Views and Controllers when I right Java - except when I use JFC components like JList, which use them - so maybe I've made some fairly big mistakes in splitting the code into different classes.
As I said, the code "feels" right but that might be my structured design instincts approving what I've done, not good OO theory.
Rhino
Bjorn Abelli - 11 Nov 2005 00:47 GMT "Rhino" wrote...
> "Bjorn Abelli" wrote... >> "Rhino" wrote...
>> To me, this rather sounds that you haven't considered >> that you possibly violate the rule of high cohesion... >> > Sorry, I don't know that rule. Can you possibly state it (briefly)? Shortest possible:
An instance of a specific class should do what it should do, and nothing else...
;-)
The concept of "high cohesion" simply states that a single class shouldn't have too much responsibilities.
It's rather easier to contrast that with the concept of "low cohesion", where the worst form is "coincidental cohesion", where parts of a module are grouped arbitrarily.
http://en.wikipedia.org/wiki/Cohesion
>> To me it now sounds like both Alpha and AlphaPreferences is doing "too >> much"... [quoted text clipped - 5 lines] > 10 methods or more than 20 class > variables or more than 500 lines of code.... Nope, the key to the division lies not in number of methods or lines of code, but in the *purpose* of those methods and lines...
This is discovered when doing a thorough OO analysis, and OO design...
> So I should think of rolling the code from > AlphaPreferences back into Alpha?? No, no, no...
Well, maybe *parts* of it...
But I couldn't really say without taking a look on *all* of the code, which I don't have any intention to do... ;-)
> I have to say that "feels" wrong: Alpha and AlphaPreferences each have > their [quoted text clipped - 9 lines] > My gut hunch says that each GUI should have its own class > to control what its doing. Absolutely! It might even be the case that a single GUI itself should be composed of instances of *several* classes, each specialized on its own task.
> Or have I misunderstood you? Possibly.
To me it rather sounds that what you call Alpha should be split into at least an Alpha and an AlphaGui, where Alpha is used by both an AlphaGui and an AlphaPreferences!
It could even be possible that AlphaPreferences should be split into AlphaPreferences and AlphaPreferencesGUI, where AlphaPreferences have an association to an Alpha, or vice versa...
Or, in the latter scenario, that you end up with an Alpha, an AlphaGUI, and an AlphaPreferencesGUI.
> I know it must be hard for you to discuss this without > actually seeing any code. My simplifications and > generalizations may not be giving you a really > good sense of what the code actually does. You're absolutely right there... ;-)
> Maybe I need to read the MVC theory again to see if I'm > putting the right code in the right places. I don't > really *THINK* in terms of Models, Views and Controllers > when I right Java - except when I use JFC components like > JList, which use them - so maybe I've made some fairly > big mistakes in splitting the code into different classes. Well, MVC is only a tiny, tiny part of OO, it's more of a theory used for implementation of just a specific kind of pattern used in OO. There's much more to OO than MVC...
And as I said above, I rather suspect that you're using too *few* classes... ;-)
// Bjorn A
Chris Uppal - 10 Nov 2005 15:55 GMT > I *think* I had to do this at some point in the fairly distant past but I > can't find an example in my source libraries. I don't think it's possible.
> By the way, is this - using the invoking class's getters - considered a > bad thing to do in OO terms? Yup ! Awful ;-)
> I'm trying to reduce the number of parameters that Alpha has to pass to > Beta when Beta is instantiated and, since Alpha has already set those > values, it seems reasonable to simply ask alpha what values those > variables have. There's nothing wrong in having a Beta ask an Alpha for the values of some settings, nothing at all. What is wrong is that a Beta should even know /that/ it's being created by an Alpha, let alone by which one. Pass /an/ Alpha to the new Beta in its constructor, and let it ask that Alpha for the data it needs. If the Alpha wants to provide /itself/ as a parameter, then that's fine, but it's no business of the Beta to know or care. By the way, that pattern is doubly good, because it means that Alphas don't have to "know" what data is needed for setting up a Beta -- so you've got some extra decoupling in there.
(As an aside, I think that you should try to avoid using the word "class" when you mean object, and in general to try to distinguish clearly between, say, the class Alpha and its instances. I wouldn't have mentioned it -- it's a bit of terminological laxness that everyone indulges in from time to time -- except that you seem to be confusing yourself with it. I suspect that if you had thought in terms of which /objects/ were doing what, then you would probably have seen the point I made in the previous paragraph by yourself.)
-- chris
Rhino - 10 Nov 2005 17:47 GMT > > I *think* I had to do this at some point in the fairly distant past but I > > can't find an example in my source libraries. > > I don't think it's possible. Bjorn's initial reply to my question demonstrates that it is possible; his approach exactly matched the approach I had used when I finally found that old example. The code works fine.
> > By the way, is this - using the invoking class's getters - considered a > > bad thing to do in OO terms? > > Yup ! Awful ;-) You're being facetious, right?
> > I'm trying to reduce the number of parameters that Alpha has to pass to > > Beta when Beta is instantiated and, since Alpha has already set those [quoted text clipped - 7 lines] > If the Alpha wants to provide /itself/ as a parameter, then that's fine, but > it's no business of the Beta to know or care. Yes, that's exactly what Bjorn's reply called for; the specific instance of Alpha which was invoking this instance of Beta was passed in Beta's constructor via a 'this' reference.
> By the way, that pattern is > doubly good, because it means that Alphas don't have to "know" what data is > needed for setting up a Beta -- so you've got some extra decoupling in there. Okay, that sounds good :-) In Bjorn's reply, he simply passes a specific instance of Alpha to the new instance of Beta via the 'this' reference and leaves the Beta instance to get what it needs via Alpha's getters. I couldn't see any real problem with that but I wanted to make sure it was not a violation of design "best practices". I'd like to do things the "best" way if I can.
> (As an aside, I think that you should try to avoid using the word "class" when > you mean object, and in general to try to distinguish clearly between, say, the [quoted text clipped - 3 lines] > thought in terms of which /objects/ were doing what, then you would probably > have seen the point I made in the previous paragraph by yourself.) I was trying to make the distinction clear by using 'Alpha' to designate the class and 'alpha' to designate the instance but I probably got sloppy and starting mixing them up at some point....
And you're right; I DO confuse myself sometimes with OO terminology. That's why I drop in and ask this kind of question on the comp.lang.java.* newsgroups occasionally; replies like yours help me get back in the habit of using the right term for the right thing.
Thanks for verifying that I'm not committing a major design blunder by passing the 'this' reference to instances of Beta :-)
Rhino
Chris Uppal - 10 Nov 2005 20:01 GMT > > I don't think it's possible. > > > Bjorn's initial reply to my question demonstrates that it is possible; his > approach exactly matched the approach I had used when I finally found that > old example. The code works fine. I had (mis)understood you to be looking for a "magic" way of finding the caller without having its identity passed in as a parameter. (Remember that you were asking about how to get a stack backtrace only a day or two ago.)
> > > By the way, is this - using the invoking class's getters - considered > > > a bad thing to do in OO terms? > > > > Yup ! Awful ;-) > > > You're being facetious, right? No, not at all, but remember that was under the impression that you were looking for something much "dirtier" than was actually the case.
But...
> Yes, that's exactly what Bjorn's reply called for; the specific instance > of Alpha which was invoking this instance of Beta was passed in Beta's > constructor via a 'this' reference. At the risk of repeating myself: it isn't part of the contract that the instance of Alpha that is passed to the Beta constructor /has/ to be the caller. If that /is/ a requirement, then the design is just as dirty as if you were using the "magic" I mentioned earlier. But I don't think that it is a requirement. The new Beta doesn't care /what/ is creating it, it /does/ care about where it should get necessary information (the Alpha), but it has no reason to care, or even think, about whether that Alpha is in any way related to the object that constructed it.
BTW. I'm not trying to tell you that you are doing anything wrong -- I don't think you are -- just attempting to clarify the issues. You seem to have pretty good design intuition, but maybe have not yet reached the point where you entirely trust it, or are able to express /why/ your intuition is right.
-- chris
Rhino - 10 Nov 2005 23:25 GMT > > > I don't think it's possible. > > > [quoted text clipped - 5 lines] > without having its identity passed in as a parameter. (Remember that you were > asking about how to get a stack backtrace only a day or two ago.) Oh, I see! I didn't realize anyone would assume that the two posts were related but I can see why you'd think they might be. In fact, the problems are unrelated. [I've solved the stackTrace thing quite simply by generating a new Exception whenever one didn't exist; that Exception is passed to the Logger via logp(..., Throwable) and the Logger classes magically create a stackTrace for the fake exception.]
> > > > By the way, is this - using the invoking class's getters - considered > > > > a bad thing to do in OO terms? [quoted text clipped - 20 lines] > reason to care, or even think, about whether that Alpha is in any way related > to the object that constructed it. I'm not sure I understand you. As I mentioned in the other subthread, Alpha is actually instantiating AlphaPreferences and some of the information that AlphaPreferences needs is the Logger and Locale instances that the specific instance of Alpha is using. I want AlphaPreferences to write log messages to the same physical file and to display text in the same language as it used in Alpha. I recognize that those are just *my* desires for this particular case though. It would certainly be possible that some other program invoking AlphaPreferences might want to direct it to use a different Logger and Locale or prompt the user for a Logger and Locale that it should use (although I don't expect anyone other than Alpha to ever want to invoke AlphaPreferences). Is that what you mean when you say that the Logger and Locale are - or are not - a requirement?
So where do we stand? Is the solution Bjorn suggested a good one for me to use? Or should I be doing things differently?
Maybe more to the point, WHY is his solution good or bad for me and why is an alternative better or worse?
> BTW. I'm not trying to tell you that you are doing anything wrong -- I don't > think you are -- just attempting to clarify the issues. You seem to have > pretty good design intuition, but maybe have not yet reached the point where > you entirely trust it, or are able to express /why/ your intuition is right. I think you're right on the money; I sometimes/often feel that I'm on the right track but I'm definitely NOT confident that I am thinking of things correctly. I just took an hour or so to read in the Java Design Patterns website - http://www.patterndepot.com/put/8/JavaPatterns.htm - but found myself getting slightly dizzy (metaphorically speaking) as I tried to digest what Cooper was saying. All indepth OO conversations cause the same 'dizziness' for me, even when they are relatively well written like Cooper's stuff. :-)
John C. Bollinger - 11 Nov 2005 04:18 GMT [...]
>>At the risk of repeating myself: it isn't part of the contract that the >>instance of Alpha that is passed to the Beta constructor /has/ to be the [quoted text clipped - 29 lines] > AlphaPreferences). Is that what you mean when you say that the Logger and > Locale are - or are not - a requirement? Chris' point is perhaps a bit subtle. It is not directly about the approach you propose, but rather about the assumptions that the code you write should be allowed to make. In particular, I believe Chris is saying that AlphaPreferrences should not assume that the Alpha passed to its constructor is in any way related to the object that triggered the constructor. It should be equally valid for any object of any class to construct an AlphaPreferrences, passing any old Alpha that it happens to take a liking to. Such behavior may turn out to not be useful, but it is a design error for AlphaPreferrences to assume that it will not happen.
 Signature John Bollinger jobollin@indiana.edu
Chris Uppal - 11 Nov 2005 15:31 GMT > I think you're right on the money; I sometimes/often feel that I'm on the > right track but I'm definitely NOT confident that I am thinking of things [quoted text clipped - 4 lines] > same 'dizziness' for me, even when they are relatively well written like > Cooper's stuff. :-) If you want my advice, then don't get too hung up on it. OO is supposed to be simple and natural, if someone is puzzling you then there's a good chance that it's /their/ fault.
For me, it's all about objects. Each object has a job to do. It is allowed to call in its friends to help it. The friends will also be given jobs to do, and may in turn call in /their/ friends. And so on... I find that it helps to think about jobs and the objects that do them in /very/ anthropomorphic terms -- as if they were real people, or at least characters in a favourite story. If you do that then your focus is on what objects are needed, and on what jobs they do, and on what information they pass between them, and when. You are not thinking about "classes" (which are an implementation technology /for/ objects). You are not thinking about code (which is just how you talk to the compiler). You are not worrying about Design Patterns. Nor about whether you are producing a "proper" OO design (since you are thinking only, or mostly, about /objects/ your design /must/ be proper OO ;-)
It may turn out not to be a very good design, but it won't be bad because it's "not OO", it'll be bad because you forgot something, or because requirements changed in a way you hadn't planned for. And even if it /does/ turn out to need changing, then there's still a good chance that, because you've been thinking in terms of the jobs that need doing (rather than, say, "what Design Pattern should I use") that the changes to the design will be simple and localised -- because it's not likely that the /jobs/ will change much.
Of course, I'm pushing my own theory of OO programming here. If you find my viewpoint puzzling or worrying, then heed the advice in my first paragraph and just ignore me...
BTW. I hadn't read the book you mentioned above. I've had a look at the Background chapter, and am not immediately impressed. For instance the paragraph:
First, you accept the premise that design patterns are important in your work. Then, you recognize that you need to read about design patterns in order to know when you might use them. Finally, you internalize the patterns in sufficient detail that you know which ones might help you solve a given design problem.
is prescriptivist nonsense. It's perfectly possible to be a good designer, or a great designer, or even a great /OO/ designer, without ever thinking about Patterns. That's where patterns /come from/. Patterns are useful tools for working programmers, no question. But IMO what they provide is a shared vocabulary for talking /about/ designs. You don't start with a Pattern and then apply it to a design, you start with a design and then ask what common patterns are present in it. If you want to tell someone about your design, your can tell them about the patterns -- it'll be easier for you to describe, and easier for them to understand. Or if someone is suggesting a modification to a design, they may describe it terms of named patterns.
But when some "authority" claims that you need to learn the patterns ("/which/ patterns?" I demand in exasperation) in order to be a good designer, then they are talking dangerous poppycock. It may be true, for some programmers, that having a "toolkit" of patterns helps them to think about designs, but even then you don't just sit down and learn the patterns. I mean, imagine if learning carpentry were like that: first you learn about hammers, then about saws, then about planes, then chisels, then... And finally, having leaned about all the tools (and got a certificate to hang on your workshop wall), you are at last allowed to touch some real wood.
I'm not saying there's anything wrong with the book's presentation of the patterns themselves. I haven't looked that far yet, it may be -- probably is -- perfectly fine. But don't let the book sucker you into thinking that the act of design consists, even in part, of choosing between available patterns. That would make /anyone/ dizzy.
Just tell the objects what jobs you want 'em to do, and then let 'em get on with it...
<end of rant>
-- chris
Chris Smith - 14 Nov 2005 02:12 GMT Hmm... Hope you don't mind if I jump in.
> It's perfectly possible to be a good designer, or > a great designer, or even a great /OO/ designer, without ever thinking about > Patterns. That's where patterns /come from/. Yes! Completely in agreement so far, and it's refreshing to hear someone else say that...
> Patterns are useful tools for > working programmers, no question. But IMO what they provide is a shared > vocabulary for talking /about/ designs. Whoops, now I think you're entirely wrong. Oh well, it was good while it lasted! :) It's become one of my pet peeves to hear people talk about patterns names in design discussions. There are a few reasons for this.
First, with a few notable exceptions, the names aren't all that standardized. Although GoF is a hugely popular book, there are still other fairly well-established books (e.g., PLoPD) that provide different names for many of the same basic ideas.
Second, and far worse, books often provide the same name for patterns but show different low-level choices, and it's easy for anyone but the pattern expert to confuse the name with this book's irrelevant implementation choices. Invariably, this causes confusion as someone thinks that the team just agreed on a bad design... and then implements it that way!
Third, even if the books do happen to agree about the details of a pattern, trying to use pattern names ends up being COUNTER-productive by blinding developers to possible design choices. Any one of the smart people who started this whole "patterns" idea will tell you that a design pattern balances good and bad aspects of a design, and that each different circumstance may merit a somewhat different balance. The popularization of the idea seems to have lost that, and the "oh, this just uses the Abstract Factory pattern" phenomenon seems to be a big part of the problem.
#3 is especially bad when the pattern name was previously used for a more general concept (for example, "proxy" and "factory"). I've seen environments where developers are berated for using the word "proxy" to apply to anything that doesn't fit the GoF book's description. It get's silly and demoralizing.
If you ask me, here's what you should do with any design patterns book.
1. Read it. Focus especially on the discussion of WHY the pattern is a good idea, not just what it looks like.
2. Try it out. Write some test code in a concrete situation that implements the patterns. Try to REALLY understand the pattern and what it provides you. Try some different implementations, if possible.
3. Forget it. Now pretend you haven't read the book. Go about design by looking at problems and finding problem-specific solutions. If the book was any good, you may be better at finding solutions... but don't use them because you recognize them from the book. Use them because they solve your problems.
Incidentally, this is the same advice I have regarding Martin Fowler's book Refactoring (at least, the catalog section of it), and to a lesser extent Joshua Bloch's book Effective Java.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Tony O'Bryan - 14 Nov 2005 02:44 GMT >> Patterns. That's where patterns /come from/. > > Yes! Completely in agreement so far, and it's refreshing to hear > someone else say that... I've been programming for 20 years in a variety of languages, and never really paid much attention to my own programming style. It's only been in the last two years or so that I've even thought about it.
In the last couple years, much ado has been made about Extreme Programming, Agile Programming, and Patterns. When I started reading about them, I was amazed to find that they were all defining how I've been programming all along.
It was amusing because I had been putting off reading about them since I thought it was going to take too much time away from actually doing stuff. It turns out that the techniques I came up with on my own out of necessity are the very same techniques that are so buzzword friendly today.
It's eerie to hear my coworker describe a pattern from TGoF and get excited about the "new" possibilities being uncovered. I have to force myself, time and again, to not repeat what has become my mantra at work: "That's the way I've always done it."
Chris Uppal - 14 Nov 2005 12:47 GMT > > Patterns are useful tools for > > working programmers, no question. But IMO what they provide is a shared > > vocabulary for talking /about/ designs. > > Whoops, now I think you're entirely wrong. Oh well, it was good while > it lasted! :) Well, we're obviously not in complete agreement, but I don't think the /dis/agreement is all that complete either...
> First, [...] > > Second, and far worse, [...] > > Third, [...] And fourth: the GoF pattern names are often poorly chosen. Also the selection of design idioms to name as "top level" Patterns seems pretty arbitrary. E.g. the whole raft of proxy/adaptor/facade/etc seem to me to be fairly trivial variations on a theme -- giving them separate names might have academic value[*], but in practice is more confusing than helpful. In fact I rarely bother to remember which is which.
([*] But as a purely academic classification I'd rather see a fully hierarchical scheme than an almost flat list.)
But going back over your points:
> First, with a few notable exceptions, the names aren't all that > standardized. Although GoF is a hugely popular book, there are still > other fairly well-established books (e.g., PLoPD) that provide different > names for many of the same basic ideas. Well, as I've said, I think that the value of patterns is as a vocabulary (the above criticism of the names notwithstanding), and in the Darwinian world of competing jargon it seems (to me, anyway) that the "other" pattern sources are stillborn. I hear people using GoF-names, but not names from other books. Which is at it should be -- the idea is to have as /few/ pattern names as possible, not to try to find names for every possible combination of ideas. We are not attempting a complete classification of design-space, just (trying to) make it easier to communicate amongst ourselves.
BTW, I don't think there are many good sources of pattern names (even ignoring the previous paragraph). I have certainly not read all the books with "pattern" in the title, nor followed the pattern community's efforts, but from the small sample of pattern writings I have seen, the breakdown seems to be: a) Useful and popular[**] catalogues of patterns. This set has only one member. b) Language-specific rehashes of members of (a). c) Books which, while being good books about design and/or implementation issues, don't contribute much to the pattern vocabulary. (PoSA2 is a good example of this. Read as a discussion of the issues and options in the design of TAO it is good; read as a pattern catalogue it is distinctly unimpressive). d) Texts which use the expression "pattern language". These are widely (and correctly, IMO) ignored.
([**] Note that being popular is a necessary precondition for being useful)
> Second, and far worse, books often provide the same name for patterns > but show different low-level choices, and it's easy for anyone but the > pattern expert to confuse the name with this book's irrelevant > implementation choices. Invariably, this causes confusion as someone > thinks that the team just agreed on a bad design... and then implements > it that way! Agreed. I use pattern names myself, since I think they are useful, but only (and deliberately) rather loosely. E..g. I'll talk of Singleton, even though I don't prohibit creating other instances (a better name would be "distinguished instance", but no language is much use if you make it up yourself ;-)
A few years ago I worked with an experience and quite competent programmer who liked to keep a copy of GoF on his desk so that he could "get the method names right"...
> #3 is especially bad when the pattern name was previously used for a > more general concept (for example, "proxy" and "factory"). I've seen > environments where developers are berated for using the word "proxy" to > apply to anything that doesn't fit the GoF book's description. It get's > silly and demoralizing. Yes, that is a problem. Or rather, I'm willing to believe that such problems occur -- I haven't experienced that situation myself (yet -- touch wood).
> If you ask me, here's what you should do with any design patterns book. > 1. [...] My take:
1) Skim it. Slow down and read more carefully if anything grabs your attention. Ignore diagrams and discussions of implementation techniques unless they /actually/ help you understand the pattern. Try to think of occasions where you have already used or seen the design idiom that the pattern names. Chances are that unless you are a complete beginner to programming (not just to OO) you will have seen a lot of them before in some guise or other. Pay closer attention to such cases -- /this/ is where you may start to feel the value of abstracting the pattern (as a concept in its own right) away from the detailed context(s).
2) Put the book on a shelf. Display it prominently if you feel so inclined. Leave it there.
3) Use any pattern names that happen to stick in your memory, especially if they are names for design idioms that you like to use, or if they are just plain catchy.
4) When someone else uses a pattern name, sneak off somewhere and re-skim the relevant section of the book. Or ask them to explain -- much better, if you have the confidence.
In due course you will converge to a loose consensus of vocabulary with the people you work with. Patterns will now start to work for you. (Or not, if your experience is more like Chris's than mine.)
> Incidentally, this is the same advice I have regarding Martin Fowler's > book Refactoring (at least, the catalogue section of it), Ugh yes (with the same caveat). The only reason to /identify/ a refactoring, let alone name it, is so that tools like Eclipse can have long menus of refactoring operations (which I never use[***]).
([***] I have always been a dedicated and enthusiastic code-shuffler, but when I'm bending code from <this> shape to <that> shape, the last thing I want is to have to express the new design as a delta from old to new, especially not in the more-or-less impoverished language of established refactorings. I just change the code.)
-- chris
iamfractal@hotmail.com - 14 Nov 2005 14:06 GMT Chris Smith skrev:
> Hmm... Hope you don't mind if I jump in.
> If you ask me, here's what you should do with any design patterns book. > [quoted text clipped - 3 lines] > > 3. Forget it. [..] I do this all the time.
I think.
.ed
-- www.EdmundKirwan.com - Home of The Fractal Class Composition.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|