tag:blogger.com,1999:blog-4084458860381242516.post1870635964847147751..comments2023-11-26T20:18:14.351-08:00Comments on Putting the tea into team: Two stylesIvan Moorehttp://www.blogger.com/profile/09119134602348298270noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-4084458860381242516.post-56242309811481583742017-05-06T03:48:23.527-07:002017-05-06T03:48:23.527-07:00Hi Ivan,
Nat Pryce has recently posted an article...Hi Ivan,<br /><br />Nat Pryce has recently posted an article that discusses the Message Obsession and Primitive Obsession code smells. Whilst not exactly an answer to your question, it might be interesting to a reader of this post.<br /><br />http://natpryce.com/articles/000816.htmlPawel Dudahttps://www.blogger.com/profile/03376986884496350112noreply@blogger.comtag:blogger.com,1999:blog-4084458860381242516.post-6797411976429123472009-02-28T02:58:00.000-08:002009-02-28T02:58:00.000-08:00Hi Philip,Many thanks for your interesting comment...Hi Philip,<BR/>Many thanks for your interesting comments. In pairing interviews, try to frame the question such that I'm looking for a simple clean solution just to the problem as set. Your comments make me think I should also ask candidates to describe the dimensions in which their solutions are more or less easy to extend.Ivan Moorehttps://www.blogger.com/profile/09119134602348298270noreply@blogger.comtag:blogger.com,1999:blog-4084458860381242516.post-68291066758757760852009-02-26T06:38:00.000-08:002009-02-26T06:38:00.000-08:00It seems to me the first style builds an abstract ...It seems to me the first style builds an abstract syntax tree, which is how parsers and compilers are usually tought in school, while the other interprets the commands directly.<BR/><BR/>Now, with your requirements an AST isn't really needed, but it would still be my first shot because this is how I am used to thinking about parsing.<BR/><BR/>In a real compiler, you would want to do more analysis on the AST before intepreting it (error-checking, optimisations, register allocations etc).<BR/><BR/>On the other hand, this code looks more like assembly than high level code, so maybe comparing this question to a compiler might not be appropriate.Rolf Rander Næsshttps://www.blogger.com/profile/02172663850827590329noreply@blogger.comtag:blogger.com,1999:blog-4084458860381242516.post-39067241380019443732009-02-25T04:13:00.000-08:002009-02-25T04:13:00.000-08:00I suspect that the style that your candidates choo...I suspect that the style that your candidates choose will be sensitive to exactly how you word the requirement. If you start by saying "the problem is to parse input that looks like this" then you'll get style 1. If you say "the problem is to feed input like this to a robot" then you're more likely to get style 2. I think a (really) good (or suspicious) candidate might push back a bit on the requirement, asking stuff like "Do you need to do anything else with the result of the parsing apart from drive the robot right now?"Dave Clealhttps://www.blogger.com/profile/07395521471748379382noreply@blogger.comtag:blogger.com,1999:blog-4084458860381242516.post-15120463580511642562009-02-23T11:13:00.000-08:002009-02-23T11:13:00.000-08:00I have looked a bit more at the maintainability of...I have looked a bit more at the maintainability of the two systems you described. <BR/><BR/>Because I have to show a bit of code, I have put the rest of this comment <A HREF="http://theknowledge.me.uk/mywiki/blog-entries/three-styles/three-styles.html" REL="nofollow">here</A>.Philip Schwarzhttps://www.blogger.com/profile/02202819885723986161noreply@blogger.comtag:blogger.com,1999:blog-4084458860381242516.post-82404303725877205652009-02-21T17:27:00.000-08:002009-02-21T17:27:00.000-08:00Hi Ivan, I realise I am going off on a tangent, bu...Hi Ivan, I realise I am going off on a tangent, but you may still find this interesting...<BR/><BR/>One thing that struck me is that although it is true that the two systems are written in two very different styles, if you look at the systems from the point of view of their extensibility, then both systems make it easy to add new Robots, but hard to add new Commands. This is because in <A HREF="http://www.objectmentor.com/resources/articles/ocp.pdf" REL="nofollow">Open Closed Principle</A> terms, they are closed against the addition of Robots, but not against the addition of Commands, i.e. when you add a new Robot, you just write new code (the code for the new Robot):<BR/><BR/>+ ShinyNewRobot implements Robot<BR/>+ {<BR/>+ public void moveOver(...){...}<BR/>+ ...<BR/>+ public void moveOnto(...){...} <BR/>+ }<BR/><BR/> but when you add a new command, you have to change existing code, i.e. every Robot (to implement the new command).<BR/><BR/> IronMan implements Robot<BR/> {<BR/> public void moveOver(...){...}<BR/> public void moveOnto(...){...}<BR/>+ public void moveInANewWay(...){...} <BR/> }<BR/> ...<BR/> Terminator implements Robot<BR/> {<BR/> public void moveOver(...){...}<BR/> public void moveOnto(...){...}<BR/>+ public void moveInANewWay(...){...} <BR/> }<BR/><BR/>This works well if you know you won't be adding new commands but may have to add new robots.<BR/>If things are the other way round however you may want to reorganise the systems so that they are closed against the addition of new commands. To do this, you move the robot movement logic into the commands:<BR/><BR/>MoveOver implements Command<BR/>{<BR/> public void moveIronMan(){...}<BR/> public void moveTerminator(){...}<BR/>}<BR/><BR/>MoveOnto implements Command<BR/>{<BR/> public void moveIronMan(){...}<BR/> public void moveTerminator(){...}<BR/>}<BR/><BR/>Now it is easy to add a new command (because you are writing new code, not changing existing code):<BR/><BR/>+ FancyNewCommand implements Command<BR/>+ {<BR/>+ public void moveIronMan(){...}<BR/>+ public void moveTerminator(){...}<BR/>+ }<BR/><BR/>but hard to add a new Robot (because you have to change existing code):<BR/><BR/> MoveOver implements Command<BR/> {<BR/> public void moveIronMan(){...}<BR/> public void moveTerminator(){...}<BR/>+ public void moveShinyNewRobot(){...}<BR/> }<BR/><BR/> MoveOnto implements Command<BR/> {<BR/> public void moveIronMan(){...}<BR/> public void moveTerminator(){...}<BR/>+ public void moveShinyNewRobot(){...}<BR/> }<BR/><BR/>Having to choose between making it easy to add new Robots or to make it easy to add new Commands, is an instance of what <A HREF="http://www.netobjectives.com/bio-ken-pugh" REL="nofollow">Puig</A> calls <B>'The Spreadsheet Conundrum'</B> (see <A HREF="http://www.amazon.com/Prefactoring-Ken-Pugh/dp/0596008740" REL="nofollow">Prefactoring</A> ) , and which moffdb explains <A HREF="http://moffdub.wordpress.com/2008/09/10/the-spreadsheet-conundrum/" REL="nofollow">here</A> .Philip Schwarzhttps://www.blogger.com/profile/02202819885723986161noreply@blogger.com