| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| To ask the question in another thread with a slightly different emphasis: If this newsgroup is dying, where should I go? Can anybody give URLs for forums or blogs that attract a reasonable amount of traffic, or has the readership of the newsgroup splintered over a large number of niche blogs? One way of being more specific about what I am looking for is to provide an example. For a while I have been writing down the sorts of things that I found myself using regularly and thinking that everybody needs to know. The result is a single web page split up into multiple sections at http://www.mcdowella.demon.co.uk/DesignNotes.html. I would be delighted if anybody actually reads it and comments, but I would also be very pleased if somebody was to take a quick glance at it and say "If you are thinking about this you really need to read book XXX or go to web site http://www.YYY" -- A.G.McDowell |
|
#2
| |||
| |||
| On Sep 11, 12:46*am, "A.G.McDowell" <mcdowe...@mcdowella.demon.co.uk> wrote: > If this newsgroup is dying, where should I go? Can anybody give URLs for > forums or blogs that attract a reasonable amount of traffic, or has the > readership of the newsgroup splintered over a large number of niche > blogs? Come here. All of the bits you have on your webpage could be posted here and will be peer reviewed. This is more likely to happen here than sitting on your site. > One way of being more specific about what I am looking for is to provide > an example. For a while I have been writing down the sorts of things > that I found myself using regularly and thinking that everybody needs to > know. The result is a single web page split up into multiple sections at > http://www.mcdowella.demon.co.uk/DesignNotes.html. I would be delighted > if anybody actually reads it and comments... In the section "Dependencies and Interfaces". What you say there is all well and good when talking about *physical* dependencies (that's what Lakos' book was about after all,) but you don't seem to touch on *logical* dependencies much at all. One can go through the effort of making an interface and then writing the client to that interface and when done one might think that "... it is not dependent on the components that implement those interfaces, so a dependency cycle never arises." (your words) but that isn't necessarily true. Remember your definition of dependency... "that component A is dependent on component B if design changes to component B can force design changes in component A". This issue just arose in the last thread of the group "Question observer design pattern." HS suggested to the OP of that thread that he should put a Registrar class between the Subject and Listener. Supposedly, doing this would mean, "The Listeners are then fully decoupled from Subject." (HS) Patrick May said much the same thing, although he called the intermediate class a "discovery protocol". As I pointed out to Patrick, and this also applies to HS's solution, these intermediates do not remove the logical dependency, they only obfuscate it. The observer still must know quite a bit about the client and it is still the case that if the client changes in any of a number of ways, the observer must change too (or possibly be made obsolete.) No matter how many interfaces or intermediate classes exist, there is still a logical connection. Now, I'm not saying that HS's and Patrick's solutions aren't sound, only that they don't reduce *logical* dependencies. If you are using them because you need to reduce *physical* dependencies then great, go for it. Just don't get the two different issues confused. |
|
#3
| |||
| |||
| A.G.McDowell wrote: > > One way of being more specific about what I am looking for is to provide > an example. For a while I have been writing down the sorts of things > that I found myself using regularly and thinking that everybody needs to > know. The result is a single web page split up into multiple sections at > http://www.mcdowella.demon.co.uk/DesignNotes.html. I would be delighted > if anybody actually reads it and comments, but I would also be very > pleased if somebody was to take a quick glance at it and say "If you are > thinking about this you really need to read book XXX or go to web site > http://www.YYY" There's something really nice about that webpage. Sort of ... charming or something. I can't put my finger on it. But it's pleasant reading. Some might find the single mass of text off-putting, but, apparently, I didn't, and continue not to do so. ..ed -- Encapsulation theory fundamentals: www.EdmundKirwan.com/pub/paper1.pdf |
|
#4
| |||
| |||
| Responding to Daniel T.... > This issue just arose in the last thread of the group "Question > observer design pattern." HS suggested to the OP of that thread that > he should put a Registrar class between the Subject and Listener. > Supposedly, doing this would mean, "The Listeners are > then fully decoupled from Subject." (HS) Patrick May said much the > same thing, although he called the intermediate class a "discovery > protocol". > > As I pointed out to Patrick, and this also applies to HS's solution, > these intermediates do not remove the logical dependency, they only > obfuscate it. The observer still must know quite a bit about the > client and it is still the case that if the client changes in any of a > number of ways, the observer must change too (or possibly be made > obsolete.) No matter how many interfaces or intermediate classes > exist, there is still a logical connection. To the extent that it is impossible for two objects to collaborate without some degree of logical coupling, that is correct. However, I think the goal is to reduce the degree of logical coupling and I think the pattern can do a good job of that. In my Registrar example the Subject logically knows nothing about who will actually respond, not even that they exist. Similarly, the Listener logically knows nothing about the Subject or even that a particular Subject exists. That comes for free as soon as one separates message from method in the OOA/D. In addition, the semantics of Registrar are such that it logically has to understand nothing about either Subject or Listener. Registrar itself has the very limited semantics of providing a mapping for conditions and objects that care about those conditions, which is can do without knowing why the condition exists, who raised it, what will be done in response to raising the condition, or why a particular object cares about the condition. Finally, the concerns about who cares about the condition are logically separated from the concerns of generating the condition and the concerns of the response to it. I think that separation and encapsulation of concerns is what mitigates the logical coupling. The coupling is still there because logically the Listener must respond to raising the condition _in the overall solution_. But the coupling has been transformed and compartmentalized so that it is quite unlikely that any requirements change related to that collaboration will require modification of more than one object involved and the modifications that are required are likely to be minor. IOW, the likelihood of shotgun refactoring to accommodate the requirements change is very small, which is the goal of the OO paradigm. To put it another way, the logical coupling has been transformed and compartmentalized so that individual objects can be designed and implemented independently of each other AND the overall solution context. (Not quite true because one abstracts objects so the abstraction is tailored to the problem in hand, but close enough for gov'ment work.) -- There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info@pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH |
|
#5
| |||
| |||
| In article <cc8be20e-55fa-495d-94e1-59ce743020f1@34g2000hsh.googlegroups ..com>, Daniel T. <daniel_t@earthlink.net> writes >On Sep 11, 12:46*am, "A.G.McDowell" <mcdowe...@mcdowella.demon.co.uk> >wrote: (trimmed) > >> One way of being more specific about what I am looking for is to provide >> an example. For a while I have been writing down the sorts of things >> that I found myself using regularly and thinking that everybody needs to >> know. The result is a single web page split up into multiple sections at >> http://www.mcdowella.demon.co.uk/DesignNotes.html. I would be delighted >> if anybody actually reads it and comments... > >In the section "Dependencies and Interfaces". What you say there is >all well and good when talking about *physical* dependencies (that's >what Lakos' book was about after all,) but you don't seem to touch on >*logical* dependencies much at all. > >One can go through the effort of making an interface and then writing >the client to that interface and when done one might think that "... >it is not dependent on the components that implement those interfaces, >so a dependency cycle never arises." (your words) but that isn't >necessarily true. Remember your definition of dependency... "that >component A is dependent on component B if design changes to component >B can force design changes in component A". > The argument is that whatever design changes component B suffers do not relieve it from the responsibility of implementing its interface. If A relies only on the interface, then B can be recoded at will, as long as it still implements this interface. Changes where I have actually seen this happen include changing a windows server to be a windows service, optimising network traffic after it had been proved to be a bottleneck, and changing an underlying database from Access to SQL Server embedded/MSDE, or whatever it is called these days. The catch, of course, is when the interface is found to be unimplementable, typically because it is not fed all the information required to do its job. >This issue just arose in the last thread of the group "Question >observer design pattern." HS suggested to the OP of that thread that >he should put a Registrar class between the Subject and Listener. >Supposedly, doing this would mean, "The Listeners are >then fully decoupled from Subject." (HS) Patrick May said much the >same thing, although he called the intermediate class a "discovery >protocol". > >As I pointed out to Patrick, and this also applies to HS's solution, >these intermediates do not remove the logical dependency, they only >obfuscate it. The observer still must know quite a bit about the >client and it is still the case that if the client changes in any of a >number of ways, the observer must change too (or possibly be made >obsolete.) No matter how many interfaces or intermediate classes >exist, there is still a logical connection. > >Now, I'm not saying that HS's and Patrick's solutions aren't sound, >only that they don't reduce *logical* dependencies. If you are using >them because you need to reduce *physical* dependencies then great, go >for it. Just don't get the two different issues confused. > It is at least traditional to use publish-subscribe in many domains, such as simulation systems. This looks a lot to me like the observer pattern extended to introduce an intermediary registrar or broker class. In practice this seems to work pretty well. In the simple case the publish-subscribe system is just a handy place to put the code that everybody needs to have to support their listeners. As such systems get more complicated, the publish-subscribe core can offer transactions in which multiple items are published atomically. In simulation systems we would like assurances that all clients agree about the order in which different events happen. We might also want to ask questions like "who is transmitting on frequency X?" or "who is in room Y of the dungeon?". If X and Y depend on data generated outside the system, e.g. by human players, you are going to end up with something that does the job of a registrar. -- A.G.McDowell |
|
#6
| |||
| |||
| "A.G.McDowell" <mcdowella@mcdowella.demon.co.uk> wrote: > Daniel T. <daniel_t@earthlink.net> writes: > > "A.G.McDowell" <mcdowe...@mcdowella.demon.co.uk> wrote: Here you go, one guy makes an assertion and the ball gets rolling! :-) > > > http://www.mcdowella.demon.co.uk/DesignNotes.html. I would be > > > delighted if anybody actually reads it and comments... > > > > In the section "Dependencies and Interfaces". What you say there > > is all well and good when talking about *physical* dependencies > > (that's what Lakos' book was about after all,) but you don't seem > > to touch on *logical* dependencies much at all. > > > > One can go through the effort of making an interface and then > > writing the client to that interface and when done one might > > think that "... it is not dependent on the components that > > implement those interfaces, so a dependency cycle never arises." > > (your words) but that isn't necessarily true. Remember your > > definition of dependency... "that component A is dependent on > > component B if design changes to component B can force design > > changes in component A". > > The argument is that whatever design changes component B suffers do > not relieve it from the responsibility of implementing its > interface. If A relies only on the interface, then B can be recoded > at will, as long as it still implements this interface. Changes > where I have actually seen this happen include changing a windows > server to be a windows service, optimising network traffic after it > had been proved to be a bottleneck, and changing an underlying > database from Access to SQL Server embedded/MSDE, or whatever it is > called these days. The catch, of course, is when the interface is > found to be unimplementable, typically because it is not fed all > the information required to do its job. But none of this actually requires a separate "interface" class. All that is required is that B have a well designed set of methods. > > This issue just arose in the last thread of the group "Question > > observer design pattern." HS suggested to the OP of that thread > > that he should put a Registrar class between the Subject and > > Listener. Supposedly, doing this would mean, "The Listeners are > > then fully decoupled from Subject." (HS) Patrick May said much > > the same thing, although he called the intermediate class a > > "discovery protocol". > > > > As I pointed out to Patrick, and this also applies to HS's > > solution, these intermediates do not remove the logical > > dependency, they only obfuscate it. The observer still must know > > quite a bit about the client and it is still the case that if the > > client changes in any of a number of ways, the observer must > > change too (or possibly be made obsolete.) No matter how many > > interfaces or intermediate classes exist, there is still a > > logical connection. > > > > Now, I'm not saying that HS's and Patrick's solutions aren't > > sound, only that they don't reduce *logical* dependencies. If you > > are using them because you need to reduce *physical* dependencies > > then great, go for it. Just don't get the two different issues > > confused. > > It is at least traditional to use publish-subscribe in many domains, > such as simulation systems. This looks a lot to me like the observer > pattern extended to introduce an intermediary registrar or broker class. > In practice this seems to work pretty well. In the simple case the > publish-subscribe system is just a handy place to put the code that > everybody needs to have to support their listeners. As such systems get > more complicated, the publish-subscribe core can offer transactions in > which multiple items are published atomically. In simulation systems we > would like assurances that all clients agree about the order in which > different events happen. We might also want to ask questions like "who > is transmitting on frequency X?" or "who is in room Y of the dungeon?". > If X and Y depend on data generated outside the system, e.g. by human > players, you are going to end up with something that does the job of a > registrar. Independent classes agreeing on the order in which different events happen, and asking questions of those classes all introduce logical dependencies, and the extra Registrar class doesn't alleviate any of that. See more in the message I'm about to write in response to HS's response. :-) Again, I'm not saying that such a system is useless, it *does* reduce physical coupling and that can be quite useful at times, it is just that making grand claims that it *removes* all dependencies is going too far. |
|
#7
| |||
| |||
| "H. S. Lahman" <hsl@pathfindermda.com> wrote: > Responding to Daniel T.... > > > This issue just arose in the last thread of the group "Question > > observer design pattern." HS suggested to the OP of that thread > > that he should put a Registrar class between the Subject and > > Listener. Supposedly, doing this would mean, "The Listeners are > > then fully decoupled from Subject." (HS) Patrick May said much > > the same thing, although he called the intermediate class a > > "discovery protocol". > > > > As I pointed out to Patrick, and this also applies to HS's > > solution, these intermediates do not remove the logical > > dependency, they only obfuscate it. The observer still must know > > quite a bit about the client and it is still the case that if the > > client changes in any of a number of ways, the observer must > > change too (or possibly be made obsolete.) No matter how many > > interfaces or intermediate classes exist, there is still a > > logical connection. > > To the extent that it is impossible for two objects to collaborate > without some degree of logical coupling, that is correct. However, > I think the goal is to reduce the degree of logical coupling and I > think the pattern can do a good job of that. I don't think so. Well designed interfaces reduce the degree of logical coupling, not the introduction of extra objects between the speaker and the listener. > In my Registrar example the Subject logically knows nothing about > who will actually respond, not even that they exist. Whoa! The Subject knows about the Registrar, so it knows that someone is listening. If the pattern is designed properly the Subject doesn't know if any listener will actually respond, but it wouldn't know that even if the Listener was connected directly to the Subject. From the Subject's POV, there is no difference between a Listener that provides "redirection via a mapping between Subject messages and the real Listeners" and a Listener that "actually care[s] about those messages." (quotes are yours.) To put this in a diagram: [Subject]--->[Listener<interface>]*<--+ A | | | +---+---+ | | | |[Listener] [Registrar]---+ A Registrar is just another kind of Listener. > Similarly, the Listener logically knows nothing about the Subject > or even that a particular Subject exists. That comes for free as > soon as one separates message from method in the OOA/D. Again, be careful of your wording. The Listener is listening for a reason, it is waiting for notification that the program is in a particular state. The only thing the pattern buys you here is that now almost any object in the system could notify the Listener of the state change it is interested in. Which leads to the kind of obfuscation I was warning about in my last post. > In addition, the semantics of Registrar are such that it logically > has to understand nothing about either Subject or Listener. > Registrar itself has the very limited semantics of providing a > mapping for conditions and objects that care about those > conditions, which is can do without knowing why the condition > exists, who raised it, what will be done in response to raising the > condition, or why a particular object cares about the condition. > Finally, the concerns about who cares about the condition are > logically separated from the concerns of generating the condition > and the concerns of the response to it. In dynamic OO languages, the system itself takes care of that job so adding the extra level of indirection provides almost no benefit. In static typed languages the extra level of indirection can reduce *physical* coupling, allowing modules to be deployed separately but it does nothing to alleviate logical coupling. > I think that separation and encapsulation of concerns is what > mitigates the logical coupling. The coupling is still there because > logically the Listener must respond to raising the condition _in > the overall solution_. But the coupling has been transformed and > compartmentalized so that it is quite unlikely that any > requirements change related to that collaboration will require > modification of more than one object involved and the modifications > that are required are likely to be minor. IOW, the likelihood of > shotgun refactoring to accommodate the requirements change is very > small, which is the goal of the OO paradigm. > > To put it another way, the logical coupling has been transformed > and compartmentalized so that individual objects can be designed > and implemented independently of each other AND the overall > solution context. (Not quite true because one abstracts objects so > the abstraction is tailored to the problem in hand, but close > enough for gov'ment work.) What you are talking about is basically a white board system. Subjects throughout the program change the state of "the environment" while Listeners monitor "the environment" for particular state changes. "The environment" is like a huge global and has all of the same problems as globals always do. |
|
#8
| |||
| |||
| Responding to Daniel T.... > I don't think so. Well designed interfaces reduce the degree of logical > coupling, not the introduction of extra objects between the speaker and > the listener. The buffer objects allow one to transform *what* the participants need to know... >> In my Registrar example the Subject logically knows nothing about >> who will actually respond, not even that they exist. > > Whoa! The Subject knows about the Registrar, so it knows that someone is > listening. If the pattern is designed properly the Subject doesn't know > if any listener will actually respond, but it wouldn't know that even if > the Listener was connected directly to the Subject. From the Subject's > POV, there is no difference between a Listener that provides > "redirection via a mapping between Subject messages and the real > Listeners" and a Listener that "actually care[s] about those messages." > (quotes are yours.) And I stand by them! B-) The Subject knows about Registrar solely as a recipient of its messages, which has nothing to do with the semantics of the messages or any response. (Note that message routing is separated from object design and is done at a different level of abstraction in OOA/D.) Subject no longer knows who cares about its messages, what responsibilities they have, or when they care (e.g., if responders are dynamically substituted). The logical concerns of routing the messages in the overall solution have been completely removed from Subject's responsibilities and delegated to Registrar. To route the messages properly Registrar needs to understand something about the context of the collaboration. Fortunately, though, by isolating and encapsulating those concerns we can provide a mechanism that is quite robust in the dynamic context while knowing the minimum about Subject and Listener semantics. IOW, we can provide a pretty mechanical and quite general implementation mechanism around the invariants of the dynamic context because we can abstract it quite generally in terms of message routing -- which would be difficult to do it were embedded in the existing semantics of Subject and Listener. >> Similarly, the Listener logically knows nothing about the Subject >> or even that a particular Subject exists. That comes for free as >> soon as one separates message from method in the OOA/D. > > Again, be careful of your wording. The Listener is listening for a > reason, it is waiting for notification that the program is in a > particular state. The only thing the pattern buys you here is that now > almost any object in the system could notify the Listener of the state > change it is interested in. Which leads to the kind of obfuscation I was > warning about in my last post. It seems to me that is kind of the point. Listener only needs to be notified; it doesn't need to know who notified it or why. [What I was mainly on about here was the bi-directional coupling suggested by the OP and the fact the the GetState collaboration described in the GoF pattern is really orthogonal to the pattern. There is no need for that reverse knowledge and it is risky to incorporate it will the pattern due to cohesion issues.] >> In addition, the semantics of Registrar are such that it logically >> has to understand nothing about either Subject or Listener. >> Registrar itself has the very limited semantics of providing a >> mapping for conditions and objects that care about those >> conditions, which is can do without knowing why the condition >> exists, who raised it, what will be done in response to raising the >> condition, or why a particular object cares about the condition. >> Finally, the concerns about who cares about the condition are >> logically separated from the concerns of generating the condition >> and the concerns of the response to it. > > In dynamic OO languages, the system itself takes care of that job so > adding the extra level of indirection provides almost no benefit. In > static typed languages the extra level of indirection can reduce > *physical* coupling, allowing modules to be deployed separately but it > does nothing to alleviate logical coupling. Au contraire! The dynamic OOPLs still marry message and method. Subject must still identify the specific object and the specific responsibility; the syntax just does a better job hiding that it is a direct procedure call. IOW, all OOPLs are based on 3GL type systems and the interface defines what the object is in terms of the responsibilities that it has. So when invoking the 3GL interface type one already knows far too much about the responder because, among other things, we name interface responsibilities for what they are. However, I don't think the OOPLs have anything to do with this. I see it is an OOA/D issue. In the OOA/D message and method are always separated so that we can define behavior responsibilities as intrinsic, self-contained properties without any temptation to worry about what other behaviors are doing. (If we do that, then the OOPL marriage of message and method becomes benign.) By separating concerns, abstracting some of them in terms of message routing invariants, and encapsulating the concerns -- pure OOA/D issues -- we reduce logical coupling and provide a design that will be robust in the face of volatile requirements. A a bonus, we ensure that we will be able to implement that design reasonably at the 3GL level despite the physical coupling issues of 3GL type systems. BTW, note that physical coupling is not an issue for OOA/D. So the registrar model was *only* dealing with logical coupling. >> I think that separation and encapsulation of concerns is what >> mitigates the logical coupling. The coupling is still there because >> logically the Listener must respond to raising the condition _in >> the overall solution_. But the coupling has been transformed and >> compartmentalized so that it is quite unlikely that any >> requirements change related to that collaboration will require >> modification of more than one object involved and the modifications >> that are required are likely to be minor. IOW, the likelihood of >> shotgun refactoring to accommodate the requirements change is very >> small, which is the goal of the OO paradigm. >> >> To put it another way, the logical coupling has been transformed >> and compartmentalized so that individual objects can be designed >> and implemented independently of each other AND the overall >> solution context. (Not quite true because one abstracts objects so >> the abstraction is tailored to the problem in hand, but close >> enough for gov'ment work.) > > What you are talking about is basically a white board system. Subjects > throughout the program change the state of "the environment" while > Listeners monitor "the environment" for particular state changes. "The > environment" is like a huge global and has all of the same problems as > globals always do. You have lost me. B-( I'm afraid I have no idea how this has anything at all to do with global data. It is separation of concerns though semantic decoupling. -- There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info@pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH |
|
#9
| |||
| |||
| "H. S. Lahman" <h...@pathfindermda.com> wrote: > Responding to Daniel T.... > > > I don't think so. Well designed interfaces reduce the degree of > > logical coupling, not the introduction of extra objects between the > > speaker and the listener. > > The buffer objects allow one to transform *what* the participants need > to know... Not at all. The Subjects still need to know what to talk about, and the Listeners still need to know what to listen for. > > > In my Registrar example the Subject logically knows nothing about > > > who will actually respond, not even that they exist. > > > Whoa! The Subject knows about the Registrar, so it knows that > > someone is listening. If the pattern is designed properly the > > Subject doesn't know if any listener will actually respond, but it > > wouldn't know that even if the Listener was connected directly to > > the Subject. From the Subject's POV, there is no difference between > > a Listener that provides "redirection via a mapping between Subject > > messages and the real Listeners" and a Listener that "actually > > care[s] about those messages." (quotes are yours.) > > And I stand by them! B-) > > The Subject knows about Registrar solely as a recipient of its > messages, which has nothing to do with the semantics of the messages > or any response. But given a well designed interface, the above is true in any case. The Subject knows about Listeners solely as recipients of its messages, which has nothing to do with the semantics of the messages or any response. The Registrar is just another kind of Listener in this regard. I again bring up my earlier diagram... [Subject]--->[Listener<interface>]*<--+ * * * * * * * * * * * A * * * * * * * | * * * * * * * * * * * | * * * * * * * | * * * * * * * * * +---+---+ * * * * * | * * * * * * * * * | * * * | * * * * * | * * * * * *[Listener] * [Registrar]---+ At the OOA level, the edge between Subject and Listener only means that subjects sends messages to listeners, there can be any number of classes/objects interposed between them, they need not even be on the same process of the same machine. As such, the Registrar class adds nothing, its just another kind of listener and the Subject knows as much about the Registrar as it does any other Listener in the system. > (Note that message routing is separated from object design and > is done at a different level of abstraction in OOA/D.) Subject no longer > knows who cares about its messages, what responsibilities they have, or > when they care (e.g., if responders are dynamically substituted). The > logical concerns of routing the messages in the overall solution have > been completely removed from Subject's responsibilities and delegated to > Registrar. It seems to me, your parenthetical note is very important. Message routing isn't part of object design, it is done at a different (and much lower) level of abstraction than OOA/D. As such, it makes no sense to introduce an object whose sole job is to *implement* message passing. Introducing such a class makes no more sense than introducing a Container class in the OOA/D model solely for the purpose of *implementing* a one-to-many relationship. > > > Similarly, the Listener logically knows nothing about the Subject > > > or even that a particular Subject exists. That comes for free as > > > soon as one separates message from method in the OOA/D. > > > Again, be careful of your wording. The Listener is listening for a > > reason, it is waiting for notification that the program is in a > > particular state. The only thing the pattern buys you here is that now > > almost any object in the system could notify the Listener of the state > > change it is interested in. Which leads to the kind of obfuscation I was > > warning about in my last post. > > It seems to me that is kind of the point. Listener only needs to be > notified; it doesn't need to know who notified it or why. Logically, that isn't the case. There is an object in the system that embodies the state change that the Listener is listening for. The OOA diagram is there to make clear what the connection is. Adding obfuscation at this level is a bad design. > [What I was mainly on about here was the bi-directional coupling > suggested by the OP and the fact the the GetState collaboration > described in the GoF pattern is really orthogonal to the pattern. There > is no need for that reverse knowledge and it is risky to incorporate it > will the pattern due to cohesion issues.] I agree completely with this. > BTW, note that physical coupling is not an issue for OOA/D. So the > registrar model was *only* dealing with logical coupling. Which is exactly why we are in this debate. IMHO, a Registrar class doesn't deal with logical coupling at all. > > > I think that separation and encapsulation of concerns is what > > > mitigates the logical coupling. The coupling is still there because > > > logically the Listener must respond to raising the condition _in > > > the overall solution_. But the coupling has been transformed and > > > compartmentalized so that it is quite unlikely that any > > > requirements change related to that collaboration will require > > > modification of more than one object involved and the modifications > > > that are required are likely to be minor. IOW, the likelihood of > > > shotgun refactoring to accommodate the requirements change is very > > > small, which is the goal of the OO paradigm. > > > > > > To put it another way, the logical coupling has been transformed > > > and compartmentalized so that individual objects can be designed > > > and implemented independently of each other AND the overall > > > solution context. (Not quite true because one abstracts objects so > > > the abstraction is tailored to the problem in hand, but close > > > enough for gov'ment work.) > > > > What you are talking about is basically a white board system. Subjects > > throughout the program change the state of "the environment" while > > Listeners monitor "the environment" for particular state changes. "The > > environment" is like a huge global and has all of the same problems as > > globals always do. > > You have lost me. B-( I'm afraid I have no idea how this has anything at > all to do with global data. It is separation of concerns though semantic > decoupling. Global state! The white board embodies state that all objects change and monitor. |
|
#10
| |||
| |||
| Responding to Daniel T.... I think we are getting hung up on the decoupling issue, which is really peripheral to what the pattern is about... >>> I don't think so. Well designed interfaces reduce the degree of >>> logical coupling, not the introduction of extra objects between the >>> speaker and the listener. >> The buffer objects allow one to transform *what* the participants need >> to know... > > Not at all. The Subjects still need to know what to talk about, and > the Listeners still need to know what to listen for. Exactly. They need to understand only themselves. >>>> In my Registrar example the Subject logically knows nothing about >>>> who will actually respond, not even that they exist. >>> Whoa! The Subject knows about the Registrar, so it knows that >>> someone is listening. If the pattern is designed properly the >>> Subject doesn't know if any listener will actually respond, but it >>> wouldn't know that even if the Listener was connected directly to >>> the Subject. From the Subject's POV, there is no difference between >>> a Listener that provides "redirection via a mapping between Subject >>> messages and the real Listeners" and a Listener that "actually >>> care[s] about those messages." (quotes are yours.) >> And I stand by them! B-) >> >> The Subject knows about Registrar solely as a recipient of its >> messages, which has nothing to do with the semantics of the messages >> or any response. > > But given a well designed interface, the above is true in any case. Certainly not true at the OOPL level since the interface *is* the object definition, especially in the OOPLs with run-time binding. > The Subject knows about Listeners solely as recipients of its > messages, which has nothing to do with the semantics of the messages > or any response. The Registrar is just another kind of Listener in > this regard. No, I think it is quite different. Listener *responds* with a specific behavior; listener supplies a very specific problem space semantics that is reflected in its interface. The nature of the decoupling transformation is that Registrar only provides a mapping of message to object, not message to behavior. That mapping is quite generic (e.g., an Object* reference) and is orthogonal to the semantics of either Subject or Listener within the problem context. One way to look at the decoupling of the pattern is that it frees Subject from needing to know anything about Listener's interface. Subject no longer needs to know that a specific Listener exists, what its responsibilities are, or how it is accessed. All Subject needs to know about is Registrar, which has no response semantics at all. > > I again bring up my earlier diagram... > > [Subject]--->[Listener<interface>]*<--+ > A | > | | > +---+---+ | > | | | >[Listener] [Registrar]---+ > > At the OOA level, the edge between Subject and Listener only means > that subjects sends messages to listeners, there can be any number of > classes/objects interposed between them, they need not even be on the > same process of the same machine. As such, the Registrar class adds > nothing, its just another kind of listener and the Subject knows as > much about the Registrar as it does any other Listener in the system. I think the diagram is a non sequitur for two reasons. First, There is no generalization; that would be a semantically quite different solution and it would be difficult to justify how the disparate Listener and Registrar semantics had an is-a relationship to a common set. IOW, it would almost always be poor problem space abstraction. Second, the interface to Registrar is not necessarily the interface to Listener, which is kind of the point. Different classes => different class semantics => different interfaces. The semantics of what Registrar does is quite different than the semantics of what Listener does and the interfaces should reflect that (e.g., Registrar::acceptEvent vs. Listener::recomputeMean). If one were anal retentive about the UML, both Registrar and Listener would have separate Interface model elements. [Technically I also have a problem with the feedback relationship since Registrars aren't related to other Registrars. But let's not go there.] >> (Note that message routing is separated from object design and >> is done at a different level of abstraction in OOA/D.) Subject no longer >> knows who cares about its messages, what responsibilities they have, or >> when they care (e.g., if responders are dynamically substituted). The >> logical concerns of routing the messages in the overall solution have >> been completely removed from Subject's responsibilities and delegated to >> Registrar. > > It seems to me, your parenthetical note is very important. Message > routing isn't part of object design, it is done at a different (and > much lower) level of abstraction than OOA/D. As such, it makes no > sense to introduce an object whose sole job is to *implement* message > passing. Introducing such a class makes no more sense than introducing > a Container class in the OOA/D model solely for the purpose of > *implementing* a one-to-many relationship. Say, what?!? We are really on different planets with that second sentence. B-( The whole point of the pattern is that: 1 * [Subject] --------------[Listener] is inadequate to express the substitution of Listeners based on dynamic solution context. That substitution is important enough to the problem solution that one wants to be quite explicit in the design about how it is handled. If you could trivially send the message to whoever is currently in the Listener collection, why bother with the pattern? The reason to use the pattern is you don't want to hide critically important decision making in the problem context in some method that instantiates the association. You want to be quite up front with the When, Why, and How of substituting Listeners. IOW, separating and encapsulating those concerns with high visibility is a high level design decision, not something you can relegate to OOP. >>>> Similarly, the Listener logically knows nothing about the Subject >>>> or even that a particular Subject exists. That comes for free as >>>> soon as one separates message from method in the OOA/D. >>> Again, be careful of your wording. The Listener is listening for a >>> reason, it is waiting for notification that the program is in a >>> particular state. The only thing the pattern buys you here is that now >>> almost any object in the system could notify the Listener of the state >>> change it is interested in. Which leads to the kind of obfuscation I was >>> warning about in my last post. >> It seems to me that is kind of the point. Listener only needs to be >> notified; it doesn't need to know who notified it or why. > > Logically, that isn't the case. There is an object in the system that > embodies the state change that the Listener is listening for. The OOA > diagram is there to make clear what the connection is. Adding > obfuscation at this level is a bad design. But Listener isn't listening for anything specific. There is a DbC precondition for executing its behavior in the solution flow of control. All Listener needs to know is that *its* precondition has been satisfied. Listener does not need to know that its precondition happens to map exactly to the postcondition of a particular Subject behavior. If all one needed to do was connect the dots between postcondition and precondition, there would be a simple 1:* association between Subject and Listener. However, deciding who belongs in the collection is somehow critical to the solution and one wants to deal with that decision making explicitly in the OOA. Registrar is about defining that mechanism, not about passing messages between Subject and Listener. Now the fact that inserting a buffer object also provides a high degree of decoupling is mostly icing on the cake. The real issue is that Registrar allows one to deal with changes to the requirements about who listens without touching either Subject or Listener. Subject still sends the same message even if it goes to a Listener from an entirely different class. That's because, per my point earlier, Subject has no knowledge of what interface the actual Listener in hand uses. [Unfortunately, because of physical coupling in the OOPLs, Registrar does need to know unless one uses object state machines and event-based collaboration. But at least Registrar's implementation is the logical place to deal with it since managing the mapping is what it does.] >> BTW, note that physical coupling is not an issue for OOA/D. So the >> registrar model was *only* dealing with logical coupling. > > Which is exactly why we are in this debate. IMHO, a Registrar class > doesn't deal with logical coupling at all. Awk?!? The mapping between preconditions and postconditions is not logical in nature? The mapping between who raises a condition and who cares about it is not logical? Message routing is not a logical aspect of solution flow of control? Sorry, but I honestly don't know how to respond to this statement. >>>> I think that separation and encapsulation of concerns is what >>>> mitigates the logical coupling. The coupling is still there because >>>> logically the Listener must respond to raising the condition _in >>>> the overall solution_. But the coupling has been transformed and >>>> compartmentalized so that it is quite unlikely that any >>>> requirements change related to that collaboration will require >>>> modification of more than one object involved and the modifications >>>> that are required are likely to be minor. IOW, the likelihood of >>>> shotgun refactoring to accommodate the requirements change is very >>>> small, which is the goal of the OO paradigm. >>>> >>>> To put it another way, the logical coupling has been transformed >>>> and compartmentalized so that individual objects can be designed >>>> and implemented independently of each other AND the overall >>>> solution context. (Not quite true because one abstracts objects so >>>> the abstraction is tailored to the problem in hand, but close >>>> enough for gov'ment work.) >>> What you are talking about is basically a white board system. Subjects >>> throughout the program change the state of "the environment" while >>> Listeners monitor "the environment" for particular state changes. "The >>> environment" is like a huge global and has all of the same problems as >>> globals always do. >> You have lost me. B-( I'm afraid I have no idea how this has anything at >> all to do with global data. It is separation of concerns though semantic >> decoupling. > > Global state! The white board embodies state that all objects change > and monitor. Well, for one thing the need for notification may have nothing to do with state variables. The relevant postcondition that is raised may simply be that Subject has transitioned to a new state in its object state machine. More to the point, though, the original, inadequate 1:* association that the pattern replaces exists to limit access to state variables. So one could argue that the entire pattern is about limiting access _to Listeners_. So I am still missing the global point. -- There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info@pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.