Utility methods, utility classes, common classes – a blob is not an abstraction

This morning, I was reading the blog of J. Michael Palermo IV, and in his recent blog post, “utility methods – are they the devil”, he asks whether utility methods are evil, and he concludes with “no”.  I don’t know about the evil part, but it caused me to reflect on my past.  While Mike is talking about utility _methods_, I’d like to address utilty _classes_.

I remember a time when I created a “Util” class and put in methods that contained everything from reading the contents of a file to putting a log message in the event viewer.  Essentially, anything I couldn’t jam into a screen went into a utility method since I wanted to share this code.

I paused and reflected because I haven’t written one of these classes in several years.  I can trace it back to my adoption of the Domain Model pattern and domain-driven design in general.  DDD stresses separation of concerns and giving each class a single responsibility.  Domain classes represent a single concept in the domain, and domain services provide one service to the application. 

When I look at a “Util” class and search for the concept it represents or its responsibility, I struggle.  I see it might be writing to files, writing to the event log, transforming XML with a provided XSLT stylesheet, etc.  When I see all these things going on, the only name that is general enough is “Util”, and that’s not an abstraction.   It’s not meaningful.  It doesn’t say anything about what’s going on inside or what the responsibility is. 

I don’t even think about it these days, but I like to create abstractions for everything (ok, not EVERYTHING).  I think it makes the application so much more maintainable, and the folks who have worked with me agree.  These aren’t my ideas, by the way.  I’m very good at stealing ideas from others:  Martin Fowler, Robert C. Martin, Michael Feathers, Kent Beck, Eric Evans, Jimmy Nielson, and many others.

Consider the following needs that might be in a “Util” class:

  • File reading/writing – I have an IFileSystem interface for when my application needs to know it is using a file.  On the other hand, if I’m reading xml data from a file, and the xml is data for system logs, IFileSystem isn’t an appropriate abstraction.  Here, I’d use ISystemLogRepository since my abstraction is a data store for SystemLog.  My application doesn’t care that it’s in xml, just that it can be retrieved.
  • Writing to event log – I’d have a ILogWriter interface with a WriteToEventLog method if my application really needed to know about the event log.  More often, my application only needs to care about logging _something_, and I’d configure Log4Net to pipe the message into the event log as one of the appenders.
  • Transform xml – I’d use an IXmlTransformer interface to front this concept for my application.  This interface would be used on the extremities of the application since in the core, there is no need for xml, only domain objects.

When I think back to my use of Util classes, I have to say it was before I was unit testing my code, before I had heard of Inversion of Control containers, and when I wrote my code very tightly coupled.  I’m not making the statement, “if you use Util classes, you are type XXXX”, that would be absurd, but since I adopted testing, loose coupling, and DDD, I haven’t written a single Util class.

Exception:  I HAVE written a util class in my integration test project called TestData.  It has static methods that populate common domain objects and save them to the database as a method to set up the context for an integration test that makes use of the the database.  In production code, I can’t find a Util class by any name.

Austin .Net User Group hosts JP Boodhoo for August 13th, 2007 meeting

This is to announce the August meeting of the Austin .Net User Group on August 13th, 2007.  JP Boodhoo is giving one of his Nothin’ But .Net courses in College Station (where I went to college), and I snagged him for a user group presentation.  Here are the full details:

Topic
Generics: They’re not just about collections (Level 300, .Net Track)
In this session participants will be introduced to advanced usages of generics outside of the realm of just strongly typed collections. They will learn about how the focus of generics in the realm of collections has clouded the fact that generics can be used to introduce powerful capabilities into your application frameworks and solutions. Practical demonstrations will be utilized to showcase how developers can immediately start harnessing the power of generics in their applications today. People will walk away with new ideas as to how they can leverage generics in their own application development.

Speaker
Jean-Paul Boodhoo

jeanpaulboodhooJean-Paul S. Boodhoo is a .NET delivery expert who has been working with the .NET Framework since beta 1 of .NET 1.0. He spends his days working as an independent consultant; helping teams realize success through agile practices and pragmatic Behavior Driven Development techniques.

He has a passion for sharing information on applied behavior driven development with .NET, and has written articles for Visual Studio magazine, DevX, Code, and MSDN that utilize BDD to pragmatically apply .NET. As well as presenting on popular podcast/screencast DotNetRocks and DNRTV Jean-Paul has had the opportunity to deliver webcasts for Microsoft on the topic of design patterns in the real world. He enjoys getting active in local user groups presenting ways that developers can harness the power of .NET to realize flexible, maintainable applications.

He has a passion for empowering developers to break the stereotypical developer mold and take the effort to break into the developer community to make their own mark. His efforts in the community have earned him a Microsoft MVP award. Jean-Paul can be reached at jp@jpboodhoo.com and makes continual efforts to update his site at http://www.jpboodhoo.com. When not developing Jean-Paul can be found relaxing with his amazing wife and their four beautiful kids.

more…

Giveaway
books, mugs

Date/Time
8/13/2007 5:30:00 PM – 8/13/2007 7:30:00 PM

Location
Microsoft Technology Center
Stonebridge Plaza, Building One, 9606 N. Mopac, Ste. 200, Austin, TX 78759
512-795-5300

Focus on the core: the most important part of the application

Technologies are coming and going faster than every before.  In this environment, how can we provide companies with a good return for their software investment.  Looking back, J2EE was all the rage.  Software executives were banking on J2EE and making significant investments.  The same thing happened with COM+, ASP 3.0, etc.  Managers were projecting significant savings by using these.  Now, where are the savings.  Many applications written with these are being rewritten in newer technologies. 

Why?  Because the applications had no core.  By core, I mean, the center of the application that describes the business domain.  Typically, these are classes and interfaces.  Creating classes using COM+ or J2EE doesn’t an application core make.  The core doesn’t care about surrounding technology. The core is your domain model.  By its design, it’s the most important part of the application, but, done well, it’s portable. 

Look around and see if you can relate to this:  A software team focuses much energy on making the database as good as possible and they create stored procedures to pull back the data as quickly as possible.  They also consider the use cases of the screens that are necessary.  Using technology X for the presentation, they make database table designs and stored procedures that return exactly what the screen needs to show to the user.  Perhaps J2EE or COM+ is used in the passage of information from the database to the UI.  Perhaps Enterprise Java Beans for COM+ components perform some transformation or calculations necessary for the screens. 

Take a step back and remove the screens.  Remove the database.  Is there any application left?  Can you point to any business rules or domain concepts left in the application after the presentation and storage components are removed?  In my experience, I’ve had to answer “no” more than once.  This is absolutely the wrong way to develop software.

Software systems should be resistant to climate change.  The technology climate is always changing.  The core is the most important part of the application, and it should be insulated against changes on the outside.  Over time presentation technologies have changed many, many times.  Data access technologies haven’t sat still either.  We still have the relational database, but the manner of using it is constantly changing. 

Software health check:  Take away the code used to talk to the database.  Take away every screen.  You should still have an application.  You should be left with your application core or domain model and domain services.  Everything should be intact. 

Handle changes in technology gracefully.  If your application has a healthy core, you will be able to upgrade to the next-generation UI.  You’ll be able to change your data access to use LINQ or an ORM without much impact.  If you don’t have a healthy core, any change in technology requires almost a wholesale rewrite.

Any software system is a large investment for a company.  That software is expected to last a LONG time.  By focusing on the core of the application (domain model), the software will be able to weather changes in the technology climate.  By creating a healthy core, your software will be able to drop and adopt technologies as necessary.  Let’s stop rewriting and rewriting and start creating healthy software.

The inspiration for this post came from Jim Shore’ s thoughts.

Baking requirements – Developing with raw ingredients is waste

I have learned an important lesson from my combined experiences at all the places I’ve worked.  That is:  raw requirements cause waste.  A term I’ve used (and have heard others use) is that requirements are either “baked” or “not baked”.  For a development team to plan an iteration, or a scope of delivery, the requirements need to be baked.  If we pull the development team into a planning session, we ensure the requirements are fully baked before the meeting.  Developers will be asking specific questions about the details of the requirements, and answers need to be readily available.

A big cause of waste is when a project manager inaccurately declares the requirements as actionable and the entire team meets.  This is the most expensive meeting you can have.  As soon as the developers ask questions, a discussion ensues among business stakeholders on what the requirements should be.  At this point, the developers sit and listen until the stakeholders finish defining what the system should do.

The above is a strong indicator that the requirements aren’t baked.  There are holes in the analysis, and it comes out as soon as a developer asks a question about the expected behavior.

TIP:  Project Managers:  ensure the requirements are fully baked BEFORE you take up the ENTIRE team’s time.  You may need help from the architect or tester, but ensure the center is not raw when the whole team is pulled in.

UPDATE:  ScottBellware was a bit confused about the context of this post (see comment below), so I thought others might be also.   This post is about behavioral requirements for a single user story.  Very small scope.  Before the team can estimate, this story must be “baked”.  Otherwise, the coding is guesswork.

Arcast – The Agile Architect podcast now online

 http://channel9.msdn.com/ShowPost.aspx?PostID=322781

The above is a link to an Arcast episode where I had a conversation with Ron Jacobs about what an Agile Architect is.  Give it a listen and tell me what you thought.  My basic point (beyond introducing Agile for those not familiar) was that the architect on an agile team is the guys who looks ahead beyond the current iteration.  I mostly agree with Sam Gentile as he outlines his views here

6 months. . . to become a better developer

Ok.  I’ll jump on this bandwagon since it is forcing me to reflect on how I can make myself a better developer.  Justice Gray started this whole thing, and I was ‘tagged’ by Bil Simser.  It’s a pretty hard question since this is the first time I’m trying to reflect on how to be a better developer.  I don’t consider myself a great developer right now, but I hope to be one some day.  What the definition of that is, I’m not sure.  Will I know it when I see it?  I have, however, progressed enough that I’m pleased with my progress so far, and I believe I’m at least keeping pace with my peers.  I can attribute my current position to voracious reading and listening.  I began this when I was deployed to Iraq with the Army in 2003.  I spent every free minute reading.  I read programming books and other material related to software, and I read all the scriptures in the Old Testament as well. 

When I returned from Iraq, I was a different developer.  I approached problems from a different angle.  By reading, I realized how much I did not know, and the more I learn, the more I learn how much I don’t know.  Since then, I’ve learned to listen to others (quite selfishly) in order to learn from them.

So here are the things I’ll do in the next 6 months to become a better developer:

  • Finish my stack-o-books.  I have a stack of software books in my office that is my “to read” stack.  My “read” stack is every bigger, but I’m not nearly finished, so I need to finish those.  They mostly consist of older software books.  I feel that if I’m to have a balance view of software, I have to have a good foundation of past research.  I approach it as engineering.  I need to understand past successes and failures so that I can apply it to today.  Perhaps some could be considered software history books, but I don’t know all the history at this point, and I certainly don’t want to be doomed to repeat it.
  • Teach more than do.  Up to this point, I’ve written a lot of code.  I’ve been a code monkey, developer, senior developer, manager, executive, and now consultant, and I’ve realized that my programming skills don’t scale.  I can only create software so fast, and then there is a limit.  In management, I started this line of thinking, but moving to consulting has brought it more to the fore-front.  As the saying goes, teach the men to fish, don’t fish for them.  I will teach more and “do” less.  By that I hope to learn more by teaching and deliver more value to my clients by enabling their staff.
  • Educate myself on other ways of developing.  At this point, I have a “default architecture” in my head that has been fine-tuned from every project I’ve worked.  It’s based in part on Domain-driven design and encompasses a lot of other OOP principles.  I prefer to use NHibernate for relation database interaction and MVC for UI whether it be web or windows programming.  But even so, I realize that I will never reach a “default architecture” and that this only represents my knowledge as of today.  There is so much working software that I haven’t studied.  I intend to acquire source code to other successful applications and study it for patterns and other knowledge that has escaped me up to this point.  Of course, some open-source applications come to mind since the source is freely available. 
  • Focus on trust.  Product owners often don’t trust the developers and developers don’t trust the product owners.  In many places, the testers don’t trust either and there is a triangle of distrust.  Each group believes they are doing a good job and the other isn’t.  This just isn’t true.  Everyone wants to do a good job, but the lack of trust sabotages productivity of the whole.  Working to form trust can save so much time and keep a project from running over budget.  If ideas can flow without everyone involved finding it necessary to “cover their butts”, we remove a whole category of “work”.  I have began this, but I have a long way to go with it.  At my clients, I will focus on the trust factor first and software second.  I believe the software will come easier when the people involved trust each other.

I’ll keep this going.  For the following 4 people, what are you going to do in the next 6 months to become a better developer?