Category: .NET Programming

Dropping The “I” From Interfaces

Blanket man

Image via Wikipedia

This is not really disruptive. It’s not even a new idea. This has been blogged about before. But one thing that I think seems to get missed is the fact that that “I” maybe keeping developers from understanding the real power of interfaces.

The way that interfaces generally get used is the “I to a type” convention. So I might have an IAuthenticationService and an AuthenticationService, or IUserRepository and UserRepository. Unfortunately, the implementation class doesn’t tell us anything about what makes him an implementation, let alone what sort of implementation. Developers begin to lose sight of the fact that the interface is the contract that everyone agrees on, and the class is an implementation of that contract. Now lots of developers know this theoretically, because it’s been beaten into their heads. It’s memorization. And you might be okay all you life just memorizing that. But I think it’s better to crystalize in your head what interfaces bring to the game. There are two suggestions floating around about what to do with the “I” in interfaces:

Use It

Some folks suggest using it as a proper noun followed by a verb to almost make a declaration of what this contract you’re about to build is for. For instance, if you are making a service that reads files from the file system, you might call your interface IReadFiles, or a calendaring service might be called ISetAppointments. This is fine, but I think it feels uncomfortable to name implementations. The IReadFiles is implemented by the FileSystemReadFiles class or it is completely removed with FileSystemFileReader class.

Lose It

The other school of thought, and the one I favor and have been practicing whenever I can for the last two years or so, is to remove the “I” completely. So my IAuthenticationService becomes AuthenticationService. This has three distinct advantages: I am now forced to name my implementation something meaningful like FormsAuthenticationService. When I am using the interface in my consuming code, it has no inkling from the name that this is an interface (which is the way you should use interfaces. Finally, it can become very clear to programmers what the Interface brings to the game. The Interface is a Generic AuthenticationService it does certain things somehow. The implementation(s) are actually more clearly defined and help developers understand how and when to use different implementations of an interface. Sometimes, just understanding that you can have multiple implementations is a breakthrough for some programmers.

I know this is the programmers last Hungarian Notation Woobee and developers don’t want to let go. But on your next small project, try dropping the “I” from your interfaces and naming your implementations with meaningful names and see how it feels. In the words of Tony Toni Tone, it “sure feels good to me”.

Did you like this? Share it:

Modern Day Software Development: “Embracing Change” – Part 2 of 2

Dilbert.com

Last week we wrote Part 1 of our 2-part series on the role change plays in Modern Software Development. If you haven't read it yet, you can do so here:  Modern Day Software Development: "Making Change Difficult".  

At AdventureTech, we realize that the only constant in software development is change. Because we have a full and deep understanding the role change plays in the software development process, we have fully embraced another common approach to managing software development: AGILE.

Defining Waste

Dictionary.com defines waste as "a useless consumption or expenditure" or even better "a use without adequate return". There is no better example of that than large upfront requirements gathering efforts with the myth of locking down all requirements early on.  

Companies claiming to be agile espousing this type of methodology are simply being dishonest with themselves and their customers about who and what they are. The simple and honest reality is that all requirements for a software development effort of any substantive size simply cannot be known upfront.  

In an agile world, decisions are made later rather than sooner. The idea behind putting off decision-making until later is that you will have more clarity into what you are building than you do early on. In Lean Software Development, An Agile Toolkit, Mary and Tom Poppendieck describe a concept of waiting until “the last responsible moment” to make decisions. It is at that time that the most data is available to make an informed and educated decision instead of a "guesstimate".  

With that in mind, AdventureTech embraces a methodology that breaks a single piece of software into several small functional pieces of software (features) that together make up the end product. We then work toward building each software feature and delivering it to the client "piece by piece", and allowing them to see working software early and often vs. late and all-at-once.

This approach keeps us from breaking out detailed requirements that may never even be built in the long run. Most software developers have seen projects with heavy, upfront requirements phases where as much as 50% of those requirements specified in the beginning never even see the light of day. If that's not waste, we don't know what is!

Change Management

Another common practice for companies not practicing agile is to have large, formal, documentation-heavy change control processes. Software vendors put these processes in place to limit the amount of change clients are allowed once the build effort has begun thereby limiting their risk (and protecting their margins).  

At AdventureTech, we embrace a process that allows change but makes it visible to the client. What that means in laymen's terms is that we believe in putting our customers in charge of what we build and how much it costs by the decisions we make together.

Close collaboration with our customers is at the core of a successful agile project. Gone are the days when software developers sequester themselves away from the "distraction of customer interaction" so they can get some "real work" done. In the agile model, the customer and the software developer form a new entity….a TEAM dedicated to buildling software. This model is extremely heavy on trust and visibility with the goal of succeeding together.

While change is much easier in an agile world, that doesn't mean it is not visible or that we are not responsible as a team for the decisions we make. When requirements are changing/growing in an agile project, a good software developer will make that visible to their customer. This allows customers to make whatever course corrections are necessary based on their specific constraints (i.e. time, money, specifications).

Conclusion

Every day, more and more companies are realizing that building software is not like other industries. While nailing down requirements like blueprints for a construction project is possible, it's not the best way to build software in today's world.

According to the Standish Report surveys (1994-2009), 68% of software projects are NOT successful (over time, over budget and/or lacking critical features). The software development status quo is not working and does not deserve to be replicated.  

At AdventureTech, we are here to help you learn why agile makes sense for your next software development project and why developing a long term relationship with us will help meet your custom software needs.

If you have questions about agile, leave a comment on this blog or call us today!

Did you like this? Share it:

Making Machine.Specifications less ‘machiney’

I have been a user of Machine.Specifications or Mspec for awhile now, and have been pretty happy with how much more readable it makes my unit testing.

If you are not familiar with Mspec it is a testing framework for context/specification that uses delegates to setup the Act, Arrange, & Assert pattern.

There are several good getting started guides if this is new to you, but here is a basic example of the structure.

    public class When_a_content_admin_asks_for_a_non_existent_page
    {
        Establish that;

        Because of;

        It Should_check_the_repository;

        It Should_present_a_blank_add_content_screen;

        It Should_auto_populate_the_url_field;
    }
	
Now of course to do unit testing you must be able to do mocking/stubbing/faking etc…, I am normally a user of Moq and that is what I use in my Mspec test to establish my mocks. While it works well, all the noise it takes to arrange all of my mocks at times bothers me. While the noise was irritating I just dealt with it because setting up mocks is just something you have to do, but luckily I recently discovered somebody else had the motivation to
actually do something about it.
 
 
 
Machine.Fakes is a compliment to Machine.Specifications and reduces the obligatory mocking and dependency injection code in your tests and replaces it with a bit of magic. Machine.Fakes itself does not depend on a particular mocking framework, it uses a plugin style that lets you use any framework of your choosing. As I write this the options available (on NuGet) are Moq, FakeItEasy, Rhino.Mocks, & NSubstitute.
 
Here is an example of a simple MVC controller test of mine using just MSpec & Moq.
public class When_a_content_admin_asks_for_a_non_existent_page
    {
        Establish that = () =>
        {
            var auth = new Mock<Authorization>();
            auth.Setup(x => x.IsContentAdmin(GivenIt.IsAny<HttpContextBase>()))
                .Returns(true);

            _repo = new Mock<ContentRepository>();
            _repo.Setup(x => x.Exists("a/bogus/url"))
                .Returns(false);

            _controller = new MeekController(_repo.Object, auth.Object);
        };

        Because of = () =>
            _result = _controller.Manage("/a/bogus/url");

        It Should_check_the_repository = () =>
            _repo.Verify(x => x.Exists("a/bogus/url"), Times.Once());

        It Should_present_a_blank_add_content_screen = () =>
            _result.AssertViewRendered().ForView("Manage");

        It Should_auto_populate_the_url_field = () =>
            (_result.AssertViewRendered().Model as Content.Manage).ManageUrl.ShouldNotBeEmpty();

        static ActionResult _result;
        static MeekController _controller;
        static Mock<ContentRepository> _repo;
}
	
 

You can see that I am Mocking both an Authorization and a ContentRepository interface, with the ContentRepository defined as a field so I can assert upon it later. Both mocks are passed into the class constructor of my system under test (SUT). Now while this is not a ton of noise we can trim it down to a more readable state with Machine.Fakes, below is my updated test.

public class When_a_content_admin_asks_for_a_non_existent_page : WithSubject<MeekController>
    {
        Establish that = () =>
            {
                The<Authorization>()
                    .WhenToldTo(x => x.IsContentAdmin(GivenIt.IsAny<HttpContextBase>()))
                    .Return(true);

                The<ContentRepository>()
                    .WhenToldTo(x => x.Exists("a/bogus/url"))
                    .Return(false);
            };

        Because of = () =>
            _result = Subject.Manage("/a/bogus/url");

        It Should_check_the_repository = () =>
            The<ContentRepository>().WasToldTo(x => x.Exists("a/bogus/url")).OnlyOnce();

        It Should_present_a_blank_add_content_screen = () =>
            _result.AssertViewRendered().ForView("Manage");

        It Should_auto_populate_the_url_field = () =>
            (_result.AssertViewRendered().Model as Content.Manage).ManageUrl.ShouldNotBeEmpty();

        static ActionResult _result;
    }
	
There are a few things to point out
  • First thing to notice is that I am inheriting from a WithSubject<> base class, this is where you specify your SUT.
  • Under the Establish we are no longer newing up any concrete mocks we are only telling Machine.Fakes of our expectations with the The<> object.
  • Without an instance of a mock you will now be using the Machine.Fakes method for inspecting if a call was made or not with the same The<> object used to setup it up.
  • Any place that you had been referencing your SUT you will replace with the Subject property.
  • Since we are no longer declaring an instance of our mocks or SUT we can remove the field declarations.
  • I am still using the GivenIt.IsAny<HttpContextBase>() from my Moq framework to establish the parameter expectation.
 
It did not reduce the lines of code a ton but but this is a pretty lean test to begin with, the important part is that we removed most of the plumbing code that had nothing to do with setting expectations.

 

Conclusion… I am a happy camper that has to type even less now.

Did you like this? Share it:

Using SubSonic 3 as a LINQ Data Provider for iSeries DB2

ibm-smallsubsonic-small    So I implemented a basic SubSonic 3 provider for iSeries DB2. Although it doesn’t yet fully conform to the SubSonic3 spec; in a short time, I was able to satisfy most of the basic needs like: CRUD operations, common column data types and schema generation.  I’m using SubSonic’s simple repository which allows me to decouple the data classes making them more flexible for testing and mocking. This post will walk through a few basic operations using SubSonic against an iSeries DB2 database and provide a few scripts to generate table mapping classes for working with existing schemas.

 

Did you like this? Share it:

Read more ...

Constraints are so… constraining

If you ask most people they will agree that a database is not a great place to inject your business related logic. However if you start asking you will find people have a wide range of definitions of business logic.

Some of the most common use’s of database constraints are NULL checks, foreign keys, unique, and default values. There are other more exotic examples such as rules, indexed views, filtered indexes, and user defined types. I find that all of these are actually business constraints and ultimately used to define how your business model should behave, and as such should not be the databases responsibility.

Data constraints vs. business constraints

To illustrate the case of a simple unique constraint imagine the following development timeline

  • Of your business customers you are only allowed to have one customer of each type, so you implement a unique constraint on the CustomerType field.
  • Now 2 months later the business model has changed and you are allowed to have unlimited customers of the type ‘Part Supplier’, your unique constraint obviously has to be removed and you have two choice either leave no database constraint or implement a more complex feature such as filtered indexes on CustomerType (which is a SQL 2008 feature and not portable should you need to migrate).
  • 6 months more go by and now your model has changed again, you are allowed to have 3 ‘Part Suppliers’ with a contract value < $100,000 and unlimited with a higher contract value. To make matters worse still the current data is breaking this constraint but the business is allowing these customers to be part of a grandfather clause. To keep a database level constraint you are now in for a real challenge; what once maybe did not seem like business related logic to begin with, now clearly is, and is very hard to express in terms of SQL.

Hopefully you are also trying to keep the quality of your application experience high, so you are performing these checks in code for pre-validation as well to give useful messages to your users. Not only are you violating DRY principles by performing all of this extra work in the database, if your application is built and tested correctly it will be constraints that are never functionally used.

What seems like basic data integrity at a simple level, once real world scenarios start to apply they quickly show their limitations.

Agility

Did you like this? Share it:

Read more ...


Connect With Us

     

Contact Us

Toll Free: (888) 373-8718
Main: (913) 402-9600
Fax: (913) 402-9603
7450 W. 130th Street
Suite 320
Overland Park, KS 66213

Upcoming events

There are currently no upcoming events.

Recent tweets