Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WTL

Low Cost Design of Useful Utility Classes

5.00/5 (1 vote)
8 Aug 2011CPOL4 min read 14.4K  
Low cost design of useful utility classes

Utilities: Design of a Compression Gadget

Utility classes in software development projects of all sizes exist with the purpose of supporting a particular functionally; from compression utilities to setting loaders are amongst the most common.

However, what is the real meaning of a utility class, and what does 'low cost' mean in this context? Without any doubt, most programmers have worked with 'utility classes' at least once, and I'm sure we'd agree that utility classes must meet certain criteria in a .NET project.

Before getting into C# code, think for a moment, from the business point of view, what design should we consider so it's affordable yet useful to the project?

The cost should be low:

  • Can be done fast
  • Easy to maintain by you or others in your team
  • Have the least amount of dependencies

Its features must:

Its implementation can:

  • Be done by a single developer.
  • Reduce the amount of code in other modules or the context of which is being used.
  • Be integrated into other components easily and without much effort.

In a previous post I wrote, not too long ago, named Stream Compression - System.IO.Compression Library – Usability Review.

I mentioned some features that a compression utility should contain, so let's go ahead and take that as the starting point now and code a utility class from scratch.

Let's take a look at the functionality that we want:

  • Flexible enough to support DeflateStream, GzipStream or any other future implementations (if API doesn't change)
  • You can use your own compression class implementation as long as it follows the same pattern.
  • It must be affordable as mentioned above.

You'll find the code file attached at the bottom of this post. You can use it freely, extend it and/or modify it as needed.

Dependencies

.NET Framework 4.0 libraries:

  • System
  • System.text. System.IO.Compression
  • System.IO

Assumptions and Limitations

DeflateStream and GzipStream classes both inherit from stream class; its core functionality seems to be similar, I'm assuming Microsoft framework designers will continue to use this pattern (if they eventually add another compression class). Furthermore, any developers who implement a compression algorithm will also be using this approach.

Usages

We want to make it as simple as possible so other developers can use it by writing very little code. Let's make it intuitive, something maybe like UtilityName.Action<the_compression_class> (file); </the_compression_class>

By inferring the class compression type, we allow it to be pluggable.

Design

  • Let's make the class static - that way another developer won't need to instantiate it (less code).
  • Since we're inferring the compression class, the best way to go will be using generic types.
  • And because we're using generic types, we need a way to instantiate it also, so let's use Activator class.

Implementation

This approach is very simple yet useful that allows using any compression class, all we need to do is find a way to create an instance of it, passed in the necessary parameters; and because the base class for the compression classes will remain "Stream", we know, we can abstract a generic functionality from it.

Stream class has one static constructor and another one protected, its implementers both DeflateStream and GzipStream heavily rely on its class constructors. This can be seen as the entry point of the actual compression functionality. That means we most likely won't need to call any other method from Stream to apply an action other than the class constructor.

Key Points

A few things I want to mention about the structure of this design:

  1. It doesn't really care what type of compression the developers selects. We're not using specific type classes inside the code anyway. Therefore, if Microsoft adds another compression class in the future, it shouldn't be a problem. No further changes will be needed inside our utility class; obviously this means that maintenance will be too little to none.
  2. To call the function, per se, doesn't require writing more than one line of code. Making it easy to use.
  3. Since the utility class is static, that means that we can integrate its functionality with other components using extension methods, for example, maybe we want to support Text compression into primitive members such as the String.

The compress function looks like:

Decompress function looks the same, except it does the opposite:

Using this functionality requires only one line of code as such:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)