Thomas Pepe

  Home  |   Contact  |   Syndication    |   Login
  11 Posts | 3 Stories | 13 Comments | 0 Trackbacks

News

Article Categories

Archives

Post Categories

Wednesday, June 6, 2012 #

This summer I went to a the Kansas City Developers Conference (April 27 and 28th, 2012).  It was fun and I learned a lot.  I have been 3 times before and this is my first time blogging on it so here goes.

What I saw:

Zen of Architecture, SpecFlow, Troubleshooting Software in Production, The Kanban Game, Improving Java & .NET Developer Collaboration, Clean Code – Writing Code for Humans*, From the Steps of The Ivory Tower, Lessons Learned: Being Agile in A Waterfall World, CernerHealthWins.com – A website that got a community to live healthier. 

 

Richard Campbell and Ted Neward gave the keynotes.  I found their predictions for the future encouraging and motivating.  All in all it was a good conference.

 

*I really liked the speech on Clean Code but I could not find a link to his presentation on his blog.  Here’s a related topic on his blog though: http://www.bitnative.com/2012/04/23/not-enough-time-to-do-it-sloppy/

I also missed the presentation on Reactive Extensions.  The speaker wrote the book on the topic.  Really, there’s only one book and he wrote it.  Also he has an interesting library on Git Hub based on Reactive Extensions.  I don’t understand his library yet but I look forward to learning more.  Here’s a link to a presentation he gave at another venue (I hope it is similar – I haven’t watched this one yet): http://www.infoq.com/presentations/Reactive-Extensions-and-ReactiveUI.  I hope to learn more about this and hopefully post my findings. 

 

My Notes

The conference seemed to ask developers to be flexible about the look of our workplaces and applications as well as our next task or our use of technology while being diligent to record our progress, communicate to other developers, and make our intentions well known.  There was a healthy dose of new technologies discussed but by far the most popular class I attended was the Clean Code class (standing room only). 

Organizing our offices around tablets instead of desktops was an interesting concept discussed by the opening keynote speaker, Richard Campbell.  He envisions an office with far fewer cubicles because cubes are set up to facilitate the keyboard and mouse interface dominant among desktops.  Because of the increasing popularity and diminishing cost of touchscreens cubicles will no longer be necessary.  What will offices look like?  Richard says it will probably look a bit like a cafeteria with private corners for heads down work and open spaces for collaboration.  It is hard to imagine some jobs without the traditional desktop, mouse, monitor (mine for instance).  Perhaps as we grow accustomed to working in cafeteria workspaces while using touchscreens we will feel differently.  Until then, I’ll stick with my keyboard, mouse, and monitor (even if I know I will be writing touch screen software).  Another point he made I thought was quite poignant was the increasing importance of how we approach the task of writing code.  It was a theme I heard throughout the conference. 

For example, this theme was repeated in Patrick Liekhus’s speech on the Zen of Architecture.  There we identified 5 pillars of software architecture: 1. the IT Environment (employers, groups, responsibilities), 2. Design 3. Human Dynamics (political baggage, stakeholders) 4. Quality (“12 ities” such as flexibility, usability, availability, etc.) 5. Business Technical Strategy.  We started with an introduction to the Zachman Framework and TOGAF to build an overall strategy then we looked at development management techniques such as prototyping, spiral, and waterfall.  Every year I have been to KCDC there are agile experts and enthusiasts.  It’s hard to find a real critic of the Agile framework at KCDC.  This year Patrick told us in his lecture that “Agile frameworks have advantages of all three aforementioned frameworks”.  He suggested that we investigate Kanban which is similar to how we do things in my office.  He then listed several tools to help developers with various stages of the development strategy, organization, and lifespan.  Before making recommendations I would agree with his statement that you should be sure that the tool solves a specific problem or answers a specific question you need answered to avoid using these tools like Maslow’s Hammer.  Among his recommendations he included:

  • Balsamiq for rapid prototyping
  • XAF another rapid prototyping tool by DevExpress
  • SpecFlow for Unit Testing
  • XPO an ORM by DevExpress – I’ve used this several years ago and I liked it.
  • NHibernate another recommended ORM
  • He also recommended that even a small development shop should have automated builds (this concept was also repeated by several speakers later over the weekend)

TestTypesByCostAndMaintenceThe SpecFlow lecture was good too.  We started by identifying Brittle Tests as those tests that are difficult to automate and when automated require more maintenance because of their tendency to break for reasons unrelated to what the tests are trying to prove.  Or as the speaker put it, “Your tests are slow and broke because of stuff you don’t care about”.  Since these are the most expensive they should be less of them.  The cheapest unit tests to maintain are the isolated method by method unit tests but they are often so incremental that many of them are needed and they mean little to nothing to end users.

Enter SpecFlow.  It reads more like acceptance test but is not as brittle.  The primary goal of SpecFlow is to be living documentation of your requirements which get to live by running as unit tests although they sound like Feature Requests or Specifications.  SpecFlow is made up of Features which contain one or more scenarios.  Features read like agile stories: In order to (Goal) As a (Role) I want to (Function).  Scenarios consist of 3 pieces that read like this, “Given (some precondition) When (some action or function) Then (some reaction to when or result of when)”.  He said that since it is living documentation you could make SpecFlow the primary source for requirement documentation.  However the scenarios are laid out in more detail than most feature requests and user requirements I work with.  This makes sense because they are fleshed out to enough detail that they can be interpreted by the SpecFlow Engine and run just like Unit Tests. 

How does this all come together?  SpecFlow can be written void of any actual code in a human readable format, see above.  The C# unit testing code uses attributes to tag all given, when, and then components referenced in SpecFlow’s scenarios.  If a scenario has all of the required components in attributes in the code the SpecFlow engine will run the test.  SpecFlow even supports code reuse by allowing given, when, and then attributes to be used by multiple tests.  It supports complex scenarios by allowing for multiple givens, whens and thens in a single scenario.

Since SpecFlow uses markup to find the appropriate methods to call it integrates nicely with other Unit Testing libraries and or any custom libraries.  Since I am a big fan of TypeMock Isolator I like the possibilities this opens up.  There are some tools that come with the SpecFlow library such as support for creating mock array tables on the fly which looked useful.  Hopefully I can flesh out some ideas I have about this in a future blog entry.

Finally Jon von Gillern left us with some his best Unit Testing Tips:

  • Red, green, refactor (obligatory TTD reference here)
  • Statics are evil unless you’re testing
  • Parameterize your steps so you can find them again using RegEx
  • Break Scenarios into small reusable pieces

The speech on troubleshooting by Patrick Delancy had me writing a few things down I think are common sense but worth repeating such as: Establish a performance baseline and keep track of it.  Sure it costs a little performance to measure performance but it’s worth it.  Keep your changes stable, localized, and be able to communicate what you are doing and what you have done.  Never re-throw an exception because you loose valuable stuff when you do that; but if you do never swallow an exception without at least logging or recovering from it because you loose valuable information there too; not to mention this will raise the potential for logic errors.  The difference between an accident and a solution is knowing what you did to fix the problem.  Being capable of reproducing the solution if a similar problem is encountered is your proof that you have a solution and not an accident.  If you create a solution instead of a happy accident you can turn a negative (losses related to the problem occurring in the first place) into a positive (gains related to understanding a lasting solution).  Then he recommended several tools:

Though I did not attend them, I did find links to the following presentations given at KCDC:

(Some links go into more depth than others) Business Oriented Development, Intro to python, Getting to the point with Sinatra, Open Source RESTful Search Solr / Link 2, Domain Driven Design and Unit Testing Patterns and Antipatterns, Android Scripting

 

Presentations I missed and could not find any resources online.  Help!

Software Quality is everyone’s responsibility, Enterprise Scalability, What makes a strong

 

Here’s a link to the entire conference (see here for other topics I missed and some presentations and speakers may be linked to from this site): http://lanyrd.com/2012/kcdc12/

 

Other presentations and blogs from speakers:

http://matterport.com/ 

http://www.notsotrivial.net/blog/?page=5

http://davidstanley.org/

http://twitter.com/#!/Darrencauthon, http://darrencauthon.posterous.com/61641417

http://jamesreggers.com/2012/05/09/presentation-getting-to-know-chromes-development-tools/

https://github.com/tyronegroves

http://jfattic.wordpress.com/2012/02/15/177/

http://www.intensivesystems.net/writings.html

http://geekswithblogs.net/jonathanfmills/archive/2012/05/14/is-it-done-really.aspx

http://lostechies.com/keithdahlby/2012/05/07/posh-git-v0-4/

http://www.integratedwebsystems.com/

http://www.nicholascloud.com/

http://weblogs.asp.net/smehaffie/

http://www.skimedic.com/blog/

http://thecuttingledge.com/

http://ferventcoder.com/

http://www.mosslover.com/

http://feeds.feedburner.com/sqlteamblogsbillg

 

Going Back

I believe I will return next year.  I seem to get more out of this conference every year I attend.  Were you there?  Did I miss something truly excellent?  Did I misunderstand some of the details I shared here today?  Please let me know.


Thursday, March 22, 2012 #

Myth 3: The source of all bad code is inept developers and stupid people

When you review code is this what you assume?  Shame on you.  You are probably making assumptions in your code if you are assuming so much already.  Bad code can be the result of any number of causes including but not limited to:

  • using dated techniques (like boxing when generics are available)
  • not following standards (“look how he does the spacing between arguments!” or “did he really just name that variable ‘bln_Hello_Cats’?”)
  • hacking around assumptions made in earlier iterations / hacking in features that should be worked into the overall design
  • using properties, methods, or techniques in a novel / novice way AKA Hacking / Tinkering (like switching on button.Text between “Hello World” and “Hello World “ //clever use of space character… sigh)
  • being redundant
  • not following the SOLID principals

The first two issues, while annoying are pretty easy to spot and can be fixed so easily.  If your coding team is made up of experienced professionals who are passionate about staying current then these shouldn’t be happening.  If you work with a variety of skills, backgrounds, and experience then there will be some of this stuff going on.  If you have an opportunity to mentor such a developer who is receptive to constructive criticism don’t be a jerk; help them and the codebase will improve.  A little patience can improve the codebase, your work environment, and even your perspective.

I often wonder how much time is actually “saved” by hacking but I wouldn’t call someone an idiot for doing it.  I believe the problem to be in the way many of us look at coding.  The problem is that coders and sometimes managers of coders think we are paid to write code;  When in fact, we are paid to solve problems for our users.  Writing code doesn’t solve problems.  Rushed developers will use what they think they know and neglect the possibility of what they don’t know.  In response to this many development shops have moved to a TDD approach because it forces developers to examine the known, the unknown the boundaries between them BEFORE writing a bunch of code

TDD debates aside, when developers can’t tell the difference between the code which is technical debt and the code that is part of the application backbone, highly coupled code is written.  Code written this way makes new bad, buggy code invisible because it’s camouflaged with all of the other bad, buggy code.  Sometimes it even makes code known to be bad seem necessary.  This provides bias toward a quality downward spiral and reduces the positive effects of writing high quality code.  What’s worse is when the bad practices are not contained, it is actually more expensive, more difficult, and less effective to follow good coding practices. 

Many of us learn new technologies, techniques, and even the problem domain on the job while fixing (more like tinkering with) the application.  We wouldn’t likely trust a bridge who’s builder learned how to build a suspension bridge while putting this one together and never went back to start over when things didn’t go according to plan.  We wouldn’t likely trust a doctor who hasn’t practiced in med school and residency.  We wouldn’t likely trust our money with an investor who invests in stocks and then sees if the stock price rises.  If we want the other professionals to try out their ideas before putting us and our assets at risk shouldn’t we do the same thing with the code we write for these professionals?

Stop Feeding the Monster!So what then, are all projects using new technologies doomed to be rewritten?  I don’t think so.  If we to plan, prioritize, keep within an appropriate scope, and pause long enough to learn and try new things in a environments outside of the application success will come faster and more easily. 

Hacking upon an existing hack is what I call “feeding the monster”.  Code monsters are anti-patterns and hacks gone wild.  The reason code monsters continue to get bigger is that they keep growing in scope, touching more and more of the application due to their godlike ability to attract dependency.  This is not the result of dumb developers. It is probably the result of avoiding design, not taking the time to understand the problems or anticipate or communicate the vision of the product.  If our developers don’t understand the purpose of a feature or product how do we expect potential customers to do so?

Forethought and organization are often what is missing from bad code.  Developers who do not use the SOLID principals should be encouraged to learn these principals and be given guidance on how to apply them.  The time “saved” by giving hackers room to hack will be made up for and then some. Not as technical debt but as shoddy work that if not replaced will be struggled with again and again. 

Bad code is not the result of dumb developers (usually) it is the result of trying to do too much without the proper resources and neglecting the right thing for the first thoughtless thing that comes into our heads.

Object oriented code is all about relationships between objects.  Coders who believe their coworkers are all fools tend to write objects that are difficult to work with, not eager to explain themselves, and perform erratically and irrationally.  If you constantly find you are surrounded by idiots you may want to ask yourself if you are being unreasonable, if you are being closed minded, of if you have chosen the right profession.  Opening your mind up to the idea that you probably work with rational, well-intentioned people will probably make you a better coder and it might even make you less grumpy.  If you are surrounded by jerks who do not engage in the exchange of ideas who do not care about their customers or the durability of the code you are building together then I suggest you find a new place to work. 

What do you think?  Are good programmers incapable of writing bad code?  Are bad programmers incapable of writing good code?  Or is it really the way we look at coding that gets us into (and out of) trouble?


Tuesday, March 6, 2012 #

Technical debt isn't sloppy code and the terms should not be used interchangeably. Technical debt is a deliberate tactic taken to overcome obstacles to reach a goal. Whereas sloppy code is often a misguided attempt at get-er-done. Technical debt is a welcome part of a healthy development life cycle. Sloppy code is not.

Wednesday, February 22, 2012 #

 

Standardsi-dont-always-follow-coding-standards-but-when-i-do-i-follow-my-own

You've probably done it.  I know I have and I'm not too proud to admit that I've stepped outside the lines a time or two and not followed my company's coding standards to a T.  Have you done the same?Please fill out my survey and tell me why.

image obtained from http://troll.me/i-dont-always-follow-coding-standards-but-when-i-do-i-follow-my-own/


Sunday, February 5, 2012 #

Should we be hiring developer pairs, groups, or by the dozen? Will we need to convince our favorite coworkers to come with us before signing on with a new company in the near future? Some sources are making the prediction that this will be a reality for software developers in the near future.

Thursday, February 2, 2012 #

Because I have moved to a new company, new position, and I am using new technologies this seems as good a time as any to change the focus of this blog.  I have received some commentary to broaden my perspective and I will take this change to change and broaden the scope of my blog.

More than just code clip_image001

I plan to include all sorts of things I come across in my job like:

  • General coding practices and SOLID coding principals
  • Interviewing and career advice
  • For other things I am passionate about like my Christian faith, exercise and diet, frugal living, landscaping, my wife and son, etc I may start another blog.  I'll link to it if / when I get around to it.

 

Thinking outside the blog clip_image003

In response to one reader's comment I should be thinking about the bigger picture.  I assure you that I do but I haven't shared those thoughts on this blog.  But that left my blog entries with very limited relevance.  I still want to provide tips to things I can't find on the web and not just add more stuff to the online pile of opinions.  My blog will still primarily be a place to share recurring issues I encounter in my career and I will I still include code examples if they are novel enough to be of interest. 

With this entry included :) hold me responsible for providing enough context for my examples to make sense and clearly articulate their relevance.

 

Communityclip_image005

I haven't engaged with other bloggers and the web like I should in this blog.  I occasionally contribute to other blogs and contact other bloggers.  Sometimes I post to forums, sometimes I email authors, bloggers, and others.  I will link to those where possible and where approval is given.  For instance, Damon Overboe is a friend of mine with great blog on similar topics that I plan to cover and I get my images from http://usasearch.gov/images?locale=en&m=false so I can use images without fear of breaking copyright laws.

 

 

Regularity  clip_image007 

I will start posting on a regular basis.  This is in part due to the fact that I have been studying for a master’s degree which I now proudly hold.  That should free up some time for a blog entry once a month or once every two weeks, I'll keep you posted.  I'll try not to say much unless I have something relevant to say (present blog entry not included).

That's it

It's a new year, I have a new job, a new baby boy, and a new blog.  I hope you like the blog.

-T


Tuesday, August 23, 2011 #

Try out html, javascript, jquery, and css here: http://jsfiddle.net

Sunday, July 31, 2011 #

Java has a handy class that retains the order in which map (dictionary in .NET) values can be iterated in the same order they were added called LinkedHashMap.

Ways to iterate (*Coding from memory without compiler = chance for syntax errors: high):

LinkedHashMap<String,String> states = new LinkedHashMap<String,String>();
states.put("AL", "Alabama");
states.put("AK", "Alaska");
for(Map.Entry<String,String> state : states.entrySet()){
  System.out.print("state: " + state.getValue());
  System.out.println(" abbreviation: " + state.getKey());
}

OR

... while(states.entrySet().iterator().hasNext()){
  System.out.print("state: " + states.entrySet().getValue());
  System.out.println(" abbreviation: " + states.entrySet().getKey());
}

I discovered the LinkedHashMap thanks to this blog entry (thanks, Nick!): http://ironboundsoftware.com/blog/2006/10/14/an-ordered-hashmap-in-java/

Other references:
http://r4r.co.in/java/advancejava/collections/basic/example/collections_basic_examples.php?qid=845
http://stackoverflow.com/questions/4110045/get-next-item-in-linkedhashmap


Though software fundamentals, patterns, and anti-patterns are by far more important and intellectually stimulating to discuss, sometimes it's difficult to move to a new set of terms. When I first learned to program, .NET was pre v1.1 and the java community was getting ready for v1.4. Naturally, I preferred java because of its price, stability, and all my college classes were java. When I got work developing .NET (a few years later) I had to interpret some of the key words from java to .NET.

For instance, getters and setters were replaced (with syntax sugar) with properties, event-interfaces were replaced by event-listener methods, and so on. When I would ask about a super class I would sometimes have to rephrase and ask for a base class to better communicate with my coworkers.

Recently I moved back to java development and a lot has changed, including me. Now I find myself on the other side of the fence. Just last week I had to replace IDictionary with Map. I have only been doing this for a couple of months now and I am starting to think more java like again. It feels good to leave the I off of the front of my interface class definitions and put my curly brackets on the same line again.

I first learned source control in Subversion but for the last 3 years I have been using TFS. I am trying to speak in TFS's terminology but SVN is so ingrained to my thinking. Check-in is the TFS for commit. I still use the word blame when I should use the TFS word annotate.

It appears that my office is sticking to TFS for java development on my eclipse. So I will continue to teach myself TFS's terminology. Perhaps this link will help me or you if you are having the same trouble: http://blogs.msdn.com/b/edhintz/archive/2011/01/18/tfs-guide-for-subversion-users.aspx

What are your thoughts? Have you had a recent change in terms at work? Do your coworkers understand you or do you need a X to Y dictionary from your previous language to your current?


Wednesday, July 27, 2011 #

CTEs or common table expressions can be used to make recursive SQL stantements.  CTEs are ANSI-99 standard.  Please read www.sql-server-performance.com/2005/cte-sql2005/ for more information.

I have only had 2 instances in my career where CTEs made sense for me to use in a pratical setting.  If you have found them more practical, please share.  The first time I needed a CTE I was displaying corporate branches from a recurssive table.  Some branches had branches, which had branches, and so on, whereas other branches ended after only a node or two.  I found many articles on displaying something like this:

category 1 > sub category 1 > sub sub category...
category 1 > sub category 2...

I found many articles online on how to do this.  If this is what you need a simple google search should get you on the right path.  The second use I have below.  I needed all of the text from a particular group concatenated together.  The closest match I could find to guide me was Carl Anderson's article on concatenating rows here: http://www.sqlservercentral.com/articles/T-SQL/67973/ .  It was almost exactly what I needed.  Since the code below is based on it  you should read that article first.  I needed a column not only to be concatenated but to be concatenated per group.  So I wrote the SQL statement below and decided to share it with you.

PS - There is always room for improvement in my code expamples so if you see something that could be better please inform me so that my instructions may be more helpful to others.  Enjoy.

declare @t as table(

      group_id int NOT NULL,

      txt varchar(max) NOT NULL,

      id int NOT NULL

      )

 

insert into @t select 0, 'Hello', 0 union select 0, ' Wor', 1 union select 0, 'ld', 2 union select 1, 'another message', 3

--insert into @t select 0, 'Apple', 0 union select 0, 'Banana', 1 union select 0, 'Grape', 2 union select 1, 'Orange', 3

 

 

;with base_cte as(

      select

                  t.txt as value,

                  t.id,

                  (

                        select top 1 id from(

                        (

                              select top 1 t2.id from @t t2

                              where t2.group_id = t.group_id AND t2.id > t.id

                              order by t2.id asc

                        )

                        union all

                              (select -1)

                        )tbl

                        order by id desc             

                  ) as nex_id,

                  t.group_id,

                  case when EXISTS(

                              select top 1 t2.id from @t t2

                              where t2.group_id = t.group_id AND t2.id < t.id

                              order by t2.id asc

                  ) then 0 else 1 end as is_terminal_value,

            (select COUNT(distinct id) from @t t2 where t2.group_id = t.group_id) as record_count_by_group,

            1 as terminator

      from @t t

)

, recurssive_cte as(

      select

            value as value_group_start,

            id,

            group_id,

            record_count_by_group,

            terminator,

            row_number() over(order by group_id, id, terminator) as row_num

      from base_cte cte

      union all

      select

            cur.value_group_start + (select nex.value from base_cte nex

                        where nex.group_id = cur.group_id and

                        nex.id = cur.row_num

                  ) as value_group_start,

            id + 1,

            group_id,

            record_count_by_group,

            terminator + 1,

            row_num + 1 as row_num

      from recurssive_cte as cur

      where

      group_id = (select group_id from base_cte nex

                        where nex.group_id = cur.group_id and

                        nex.id = cur.row_num

        )

      and row_num <= record_count_by_group

)

, grouped_cte as (

      select max(value_group_start) as items

      from recurssive_cte

      where terminator = record_count_by_group

      group by group_id

)

--select * from base_cte

--select * from recurssive_cte

select * from grouped_cte