Prev: Last Call for Papers Reminder (extended): The World Congress on Engineering WCE 2010
Next: CFP CGVCVIP 2010: new date - until 29 March 2010
From: Vladimir Jovic on 3 May 2010 08:06 johnzabroski(a)gmail.com wrote: > On Apr 30, 5:22 pm, "johnzabro...(a)gmail.com" <johnzabro...(a)gmail.com> > wrote: >> On Apr 29, 4:50 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote: >> >>> What are alternatives? How to fix such architecture? > > Model the problem -- I can't really give better advice without knowing > something about the problem. Based on experience with this code > smell, where superclasses are pervasively controlling leaf classes, I > can *guess* what the general solution would look like, but I don't > want the general solution to be your *actual* solution. So what > follows is my analysis of the meta-problem, not the problem domain > itself. > > If you are writing code in a way such that superclasses are > controlling leaf classes, then you have a Specification where the > problem can be broken down into Stages (what you are currently using > classes with arbitrary names for). If at each Stage you cannot > predict what the sequences of actions will be, then you also need a > Sequence abstraction so that each Stage is composed of Sequences. But > this analysis is not complete; you need to recursively specify what > the specification of each stage and sequence is. In other words, a > Sequence must collaborate with a SequenceSpecification and a Stage > must collaborate with a StageSpecification. A StageSpecification is > composed of SequenceSpecifications, so that when you want to reuse the > Stage, you instead focus on reusing its Specification, giving you a > degree of freedom in how to implement the Stage by taking advantage of > what the Specification *doesn't* say. This analysis will allow you to > *easily* apply parametric polymorphism on-demand at each Stage and > Sequence, as well as allow for implementation hiding. It looks like you are forming a state chart. > > Your current solution doesn't really allow parametric polymorphism in > a safe way, and it doesn't allow for implementation hiding since the > parent superclasses must know about their child subclasses in order to > properly control them. > In other words, use "tell, don't ask" principle to remove the super classes. Correct? btw what tools are you using to model the problem? I modelled few things, but only on paper. Today I thought of trying kivio to model a problem I am facing.
From: johnzabroski on 4 May 2010 11:35 On May 3, 8:06 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote: > johnzabro...(a)gmail.com wrote: > > On Apr 30, 5:22 pm, "johnzabro...(a)gmail.com" <johnzabro...(a)gmail.com> > > wrote: > >> On Apr 29, 4:50 am, Vladimir Jovic <vladasp...(a)gmail.com> wrote: > > >>> What are alternatives? How to fix such architecture? > > > Model the problem -- I can't really give better advice without knowing > > something about the problem. Based on experience with this code > > smell, where superclasses are pervasively controlling leaf classes, I > > can *guess* what the general solution would look like, but I don't > > want the general solution to be your *actual* solution. So what > > follows is my analysis of the meta-problem, not the problem domain > > itself. > > > If you are writing code in a way such that superclasses are > > controlling leaf classes, then you have a Specification where the > > problem can be broken down into Stages (what you are currently using > > classes with arbitrary names for). If at each Stage you cannot > > predict what the sequences of actions will be, then you also need a > > Sequence abstraction so that each Stage is composed of Sequences. But > > this analysis is not complete; you need to recursively specify what > > the specification of each stage and sequence is. In other words, a > > Sequence must collaborate with a SequenceSpecification and a Stage > > must collaborate with a StageSpecification. A StageSpecification is > > composed of SequenceSpecifications, so that when you want to reuse the > > Stage, you instead focus on reusing its Specification, giving you a > > degree of freedom in how to implement the Stage by taking advantage of > > what the Specification *doesn't* say. This analysis will allow you to > > *easily* apply parametric polymorphism on-demand at each Stage and > > Sequence, as well as allow for implementation hiding. > > It looks like you are forming a state chart. It's not a state chart, it is a collaboration diagram (technically, not a diagram, since I described the solution in text). State charts explicitly define execution semantics. What I am instead doing is saying, you are using "class" to represent a Stage class, and methods to represent a Sequence class, and inheritance to represent sequential coupling. I am then saying that what you are doing is mathematically not versionable, because you have no way to predict paths through the system used by existing clients, especially in an open system (e.g., not a "small in-house system" or "embedded system"). Also, the collaboration diagram represents modeling process refinement, whereas state charts can model reactive systems. I can discuss the details as to why this is different some other time (or forget about it). > > Your current solution doesn't really allow parametric polymorphism in > > a safe way, and it doesn't allow for implementation hiding since the > > parent superclasses must know about their child subclasses in order to > > properly control them. > > In other words, use "tell, don't ask" principle to remove the super > classes. Correct? > > btw what tools are you using to model the problem? > I modelled few things, but only on paper. Today I thought of trying > kivio to model a problem I am facing. I honestly don't use tools. A text editor, some auto-complete, a web browser, a 30" monitor, and two 20" vertical monitors is all you need.
From: Garrett Smith on 14 May 2010 17:38 johnzabroski(a)gmail.com wrote: > On Apr 16, 9:00 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: >> Daniel T. wrote: >>> The heuristics alone as a bald list do seem a bit rough, but you have to >>> remember there is an almost 400 page book that goes along with them. >>> Also, keep in mind, the book was written in 1996 when people were new to >>> OO. Now, some of the heuristics are things that are an ingrained part of >>> the community. >> Ah, if only it were true with javascript community. Take a look at, for >> example, Dojo or MooTools. [snip signature] > > Interesting. I would love examples of shitty Javascript code. Where > should I start looking? > OK, but to make to make a good assessment of a piece of code, the language, and problem context needs to be understood. A fundamental difference with web apps is variant deployment environment. Could be IE6, Chrome Frame, various JScript builds, Opera masking as IE, iPhone, Blacberry 9000. > I don't think the problem is especially unique to prototype-based > languages like Javascript, though... No, but there are significant problems that contribute to really bad javascript. There are many many ways to cause problems in code, both with strategies and overall design. ECMAScript is a simple but flexible and powerful dynamic language yet taken for something that is not real programming. RIA development is relatively new and there is much bad advice and misinformation. Interviews for front end engineering are hard on both ends (interviewer and interviewee). With so much misinformation what should the interviewer ask? What should he trust? With such a great amount of misinformation and harmful advice, the majority of web developers hired are really quite bad at what they do. Variations exist in implementations of the language itself and especially in various browser DOMs which were historically awful. Historically, browser detection has been used to address these and other issues. A consequential effect of that is that it obfuscates the problem. With little information on how to solve such problems, developers turned to javascript libraries. These things are now considered to be "de facto" industry standard. So with all that, lets take a look at a popular javascript library: jQuery. No problem and no context is presented here, only the constructor, which is oddly placed in the prototype as `jQuery.prototype.init`. It is not necessary to know what it is doing to see that the number of loops and `if` and `else` statements is quite high. For those who know the HTML DOM, it is still an eyesore to look at. | init: function( selector, context ) { | var match, elem, ret, doc; | | // Handle $(""), $(null), or $(undefined) | if ( !selector ) { | return this; | } | | // Handle $(DOMElement) | if ( selector.nodeType ) { | this.context = this[0] = selector; | this.length = 1; | return this; | } | | // The body element only exists once, optimize finding it | if ( selector === "body" && !context ) { | this.context = document; | this[0] = document.body; | this.selector = "body"; | this.length = 1; | return this; | } | | // Handle HTML strings | if ( typeof selector === "string" ) { | // Are we dealing with HTML string or an ID? | match = quickExpr.exec( selector ); | | // Verify a match, and that no context was specified for #id | if ( match && (match[1] || !context) ) { | | // HANDLE: $(html) -> $(array) | if ( match[1] ) { | doc = (context ? context.ownerDocument || context : | document); | | // If a single string is passed in and it's a single tag | // just do a createElement and skip the rest | ret = rsingleTag.exec( selector ); | | if ( ret ) { | if ( jQuery.isPlainObject( context ) ) { | selector = [ document.createElement( ret[1] ) ]; | jQuery.fn.attr.call( selector, context, true ); | | } else { | selector = [ doc.createElement( ret[1] ) ]; | } | | } else { | ret = buildFragment( [ match[1] ], [ doc ] ); | selector = (ret.cacheable ? ret.fragment.cloneNode(true) : | ret.fragment).childNodes; | } | | return jQuery.merge( this, selector ); | | // HANDLE: $("#id") | } else { | elem = document.getElementById( match[2] ); | | if ( elem ) { | // Handle the case where IE and Opera return items | // by name instead of ID | if ( elem.id !== match[2] ) { | return rootjQuery.find( selector ); | }| | | // Otherwise, we inject the element directly into the jQuery object | this.length = 1; | this[0] = elem; | } | | this.context = document; | this.selector = selector; | return this; | } | | // HANDLE: $("TAG") | } else if ( !context && /^\w+$/.test( selector ) ) { | this.selector = selector; | this.context = document; | selector = document.getElementsByTagName( selector ); | return jQuery.merge( this, selector ); | | // HANDLE: $(expr, $(...)) | } else if ( !context || context.jquery ) { | return (context || rootjQuery).find( selector ); | | // HANDLE: $(expr, context) | // (which is just equivalent to: $(context).find(expr) | } else { | return jQuery( context ).find( selector ); | } | | // HANDLE: $(function) | // Shortcut for document ready | } else if ( jQuery.isFunction( selector ) ) { | return rootjQuery.ready( selector ); | } | | if (selector.selector !== undefined) { | this.selector = selector.selector; | this.context = selector.context; | } | | return jQuery.makeArray( selector, this ); | }, No for loops in that method, but a combined total of 21 if and else statements over 104 SLOC. That is the entry point for most jQuery programs and it is one of the simpler and more clearly defined methods. -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
From: johnzabroski on 21 May 2010 12:19
On May 14, 5:38 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > johnzabro...(a)gmail.com wrote: > > On Apr 16, 9:00 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > >> Daniel T. wrote: > >>> The heuristics alone as a bald list do seem a bit rough, but you have to > >>> remember there is an almost 400 page book that goes along with them. > >>> Also, keep in mind, the book was written in 1996 when people were new to > >>> OO. Now, some of the heuristics are things that are an ingrained part of > >>> the community. > >> Ah, if only it were true with javascript community. Take a look at, for > >> example, Dojo or MooTools. > > [snip signature] > > > > > Interesting. I would love examples of shitty Javascript code. Where > > should I start looking? > > OK, but to make to make a good assessment of a piece of code, the > language, and problem context needs to be understood. A fundamental > difference with web apps is variant deployment environment. Could be > IE6, Chrome Frame, various JScript builds, Opera masking as IE, iPhone, > Blacberry 9000. > > > I don't think the problem is especially unique to prototype-based > > languages like Javascript, though... > > No, but there are significant problems that contribute to really bad > javascript. > > There are many many ways to cause problems in code, both with strategies > and overall design. > > ECMAScript is a simple but flexible and powerful dynamic language yet > taken for something that is not real programming. > > RIA development is relatively new and there is much bad advice and > misinformation. > > Interviews for front end engineering are hard on both ends (interviewer > and interviewee). With so much misinformation what should the > interviewer ask? What should he trust? With such a great amount of > misinformation and harmful advice, the majority of web developers hired > are really quite bad at what they do. > > Variations exist in implementations of the language itself and > especially in various browser DOMs which were historically awful. > > Historically, browser detection has been used to address these and other > issues. A consequential effect of that is that it obfuscates the problem. > > With little information on how to solve such problems, developers turned > to javascript libraries. These things are now considered to be "de > facto" industry standard. > > So with all that, lets take a look at a popular javascript library: > jQuery. No problem and no context is presented here, only the > constructor, which is oddly placed in the prototype as > `jQuery.prototype.init`. > > It is not necessary to know what it is doing to see that the number of > loops and `if` and `else` statements is quite high. For those who know > the HTML DOM, it is still an eyesore to look at. > > | init: function( selector, context ) { > | var match, elem, ret, doc; > | > | // Handle $(""), $(null), or $(undefined) > | if ( !selector ) { > | return this; > | } > | > | // Handle $(DOMElement) > | if ( selector.nodeType ) { > | this.context = this[0] = selector; > | this.length = 1; > | return this; > | } > | > | // The body element only exists once, optimize finding it > | if ( selector === "body" && !context ) { > | this.context = document; > | this[0] = document.body; > | this.selector = "body"; > | this.length = 1; > | return this; > | } > | > | // Handle HTML strings > | if ( typeof selector === "string" ) { > | // Are we dealing with HTML string or an ID? > | match = quickExpr.exec( selector ); > | > | // Verify a match, and that no context was specified for #id > | if ( match && (match[1] || !context) ) { > | > | // HANDLE: $(html) -> $(array) > | if ( match[1] ) { > | doc = (context ? context.ownerDocument || context : > | document); > | > | // If a single string is passed in and it's a single tag > | // just do a createElement and skip the rest > | ret = rsingleTag.exec( selector ); > | > | if ( ret ) { > | if ( jQuery.isPlainObject( context ) ) { > | selector = [ document.createElement( ret[1] ) ]; > | jQuery.fn.attr.call( selector, context, true ); > | > | } else { > | selector = [ doc.createElement( ret[1] ) ]; > | } > | > | } else { > | ret = buildFragment( [ match[1] ], [ doc ] ); > | selector = (ret.cacheable ? ret.fragment.cloneNode(true) : > | ret.fragment).childNodes; > | } > | > | return jQuery.merge( this, selector ); > | > | // HANDLE: $("#id") > | } else { > | elem = document.getElementById( match[2] ); > | > | if ( elem ) { > | // Handle the case where IE and Opera return items > | // by name instead of ID > | if ( elem.id !== match[2] ) { > | return rootjQuery.find( selector ); > | }| > | > | // Otherwise, we inject the element directly into the jQuery object > | this.length = 1; > | this[0] = elem; > | } > | > | this.context = document; > | this.selector = selector; > | return this; > | } > | > | // HANDLE: $("TAG") > | } else if ( !context && /^\w+$/.test( selector ) ) { > | this.selector = selector; > | this.context = document; > | selector = document.getElementsByTagName( selector ); > | return jQuery.merge( this, selector ); > | > | // HANDLE: $(expr, $(...)) > | } else if ( !context || context.jquery ) { > | return (context || rootjQuery).find( selector ); > | > | // HANDLE: $(expr, context) > | // (which is just equivalent to: $(context).find(expr) > | } else { > | return jQuery( context ).find( selector ); > | } > | > | // HANDLE: $(function) > | // Shortcut for document ready > | } else if ( jQuery.isFunction( selector ) ) { > | return rootjQuery.ready( selector ); > | } > | > | if (selector.selector !== undefined) { > | this.selector = selector.selector; > | this.context = selector.context; > | } > | > | return jQuery.makeArray( selector, this ); > | }, > > No for loops in that method, but a combined total of 21 if and else > statements over 104 SLOC. That is the entry point for most jQuery > programs and it is one of the simpler and more clearly defined methods. > -- > Garrett > comp.lang.javascript FAQ:http://jibbering.com/faq/ Garrett. Thanks for taking the time to reply. I tend to agree that many GUIs are not as purely object-oriented as their marketing teams say they are. WPF is a good example. I've written several blog posts about design flaws in WPF[1], and how it allows permiscuous access to effectively global objects. What is most interesting is that WPF's dependency change propagation subsystem actually doesn't like random ranges to global objects, and doing so brings the system to its knees. The Visual Studio 2010 product team quickly "discovered" this [2]. I also discuss RIA models on my blog, at least once (that I can remember), disecting a particular "architecture" I did not like because it had no way to handle partial failure, or fail gracefully [3]. I also wrote a blog post about how to design data presentation controls in a modular fashion, but never really got around to explaining the OO solution of converting a dynamic behavior problem into a dynamic relationship participation problem [4] [1] http://z-bo.tumblr.com/post/113891179/wpf-design-flaws-part-1 [2] http://blogs.msdn.com/visualstudio/archive/2010/03/02/wpf-in-visual-studio-2010-part-2-performance-tuning.aspx [3] http://z-bo.tumblr.com/post/246854981/what-is-sofea-what-is-soui [4] http://z-bo.tumblr.com/post/378279345/re-gridview-with-variable-number-of-columns |