Breaking the Rules Part III: Create Consistency Now – Not Later

Break the Rule: I will come back to this code later and make it better.

Start creating consistency now, not later. Consistency can be a benchmark of quality. Only if the thing done consistently is of high quality. It could have a negative effect if you consistently implemented something using lower quality standards. What you want to achieve in your software solution is a consistent implementation of quality that can be quantified or measured.

You can use the measurements of quality mentioned in the previous articles or create your own set of quality standards. The entire development team should understand what the standards are and how to achieve them consistently. You will also need to put mechanisms in place to ensure your quality by measurement. This can be done by unit testing, performance and load testing, informal and formal code reviews, code refactoring, configuration management, automated deployment processes, and system monitoring. In general, use good tools and processes to create consistency.

Consistency happens over time. Measure and report the results of quality to the team. Use comparisons to previous time periods to show improvements in quality or to show that there needs to be more attention to a specific item of quality.

Breaking the Rules Part II: Stop the Method Madness

Break the Rule: Implement business logic in methods or operations.

From the beginning, developers implement logic in methods. This is fundamental to programming because you need to execute code and logic. I’m not saying that we cannot use methods or operations in our code – this would be impossible. However, we need to stop putting valuable business logic in methods.

When we do this our application logic becomes a method calling a method, calling another method and so on. The logic is a chain of methods executing to create the desired behavior. There may be certain scenarios where using this approach is acceptable. However, the context that we are concerned about is implementing business logic.

Using single methods or method-chains is difficult or at times impossible to test. You cannot isolate the specified unit to test because there are dependencies in the other methods called. Therefore, since it so difficult to unit test – you probably do not create unit tests. Not unit testing is like going on a road trip without car insurance, road-side assistance, or even checking the dashboard to determine if you have enough fuel for the trip. I have seen people approach software without the securities of unit tests. But I do not see many people driving across the desert with extremely bald tires. Again, why do we take precautions in real-life when things matter, but do not take any when developing a software solution that costs thousands and sometimes millions of dollars.

Adding new behavior becomes more difficult in method-based business logic. You will start to see and smell the “if, then” clauses scattered throughout the methods. In the beginning of a software project, the difficulties of this approach are not as evident. Yes, there are few “if, thens”, but everything seems to be working fine. They become a dark chaotic reality later in the project. This is when discussions start about re-writing the application and doing it right this time. When in reality there wasn’t anything stopping you from doing it right from the beginning.

Treat business logic like first-class citizens in your application. Do not use methods. Implement them in classes so that you can benefit from object oriented features. You get object inheritance and sharing of common behaviors in base classes. You also get more extensibility opportunities using a class approach. Another benefit, is that your classes are easier to unit test.

The Vergosity Framework allows you to use this class-driven approach to implementing business logic. You can create your own framework – it is easy to do using a simple design pattern called Template Method.

Breaking the Rules Part I: Create Quality Software the First Time

Break the Rule: You do not have time not to do it the right way the first time.

There seems to be some unwritten rule that you do not have time to do it right the first time. Break this rule now. You do not have time not to do it right the first time.

Let’s face it, there is always a business end to developing software. There is a need and addressing that need quickly makes a difference. Hopefully, the business end (management) has a plan or a product road map. It is called a road map for a reason – there is a starting point, a destination, and points of interest along the way. There may be short-cuts to your destination, but you still have a road to travel and a distance between here and there.

For this reason, you need to plan for a successful road trip. You will need to meet milestones and deliver software features, that is what you do and that is what makes you valuable. Since there will be a need for your services for this journey, doing it the right way the first time will allow you to continue and end the road trip successfully.

As a developer though, how many times have you seen a project that seemed perfect in the beginning turn out to be total chaos down the road? Why does this happen? It happens because it becomes more difficult to add new features and deliver on time as the source code becomes more complex. There was never a plan to handle the complexity that came later. There was never a plan in place to create consistent and maintainable code. There was never a plan to create unit tests to determine what is and what is not working – kind of like a dashboard on your car. The “Check Software Engine” light is on, but no one knows what to do.

Only a fool would start a road trip without checking the oil and tires. In real life, we do the right things because they are important. In software development, it should be the same way. I guarantee that doing it the right way the first time doesn’t take more time. You can deliver more features and deliver them on time. You will hit the milestones of the project. And the best benefit is that you will enjoy the journey along the way until you reach your destination. I have seen small and large teams do this. It is not impossible.

Here are five (5) ways to create quality software the first time.

  1. Create business logic using classes – create a framework, or use the Vergosity framework
  2. Implement business rules using a Business Rule Engine – create a rule engine, or use the Vergosity Business Rule engine.
  3. Implement unit testing early and throughout the development process. This is your safety net – kind of like road-side insurance.
  4. Implement logging for your application early.
  5. Use a well-defined architecture that includes proper abstraction between the layers of your application.

Vergosity Rule Engine + Fluent API

The Vergosity Rule Engine is now easier to use with Fluent API features. Basically, there is a ValidationContext object that  you can add and configure rules using fluent API style syntax. If you are not familiar with the ValidationContext – it is contained in the Vergosity.Validation namespace. And if you are not familiar with Vergosity, you can get from Nuget: Install-package Vergosity.Framework. Or search by “Vergosity” in your “Manage Nuget Packages” reference option.

image

ValidationContext

The Vergosity Rule Engine contains a set of rules already implemented. You can start by adding them to an instance of the ValidationContext. There are (2) ways to use the new Fluent API. You just need to create an instance of the ValidationContext.

ValidationContextBase context = new ValidationContext();

Simple

Option 1, shown below is the easiest way to add a new rule to the ValidationContext. All of the new Fluent API calls are prefixed using “With”. This provides a nice filter for your methods. Below, an entity is setup for the unit test and is used as the target parameter in the IsNotNull rule.

image

When you call the RenderRules() method of the ValidationContext – you can retrieve the results from the Results list. You can use the results any way you prefer in your application. The ValidationContext also contains results filtered by the Severity indicated in the rule configuration.

  • ValidationContext.ExceptionResults;
  • ValidationContext.InformationResults;
  • ValidationContext.WarningResults;

image

With Configuration

The unit test below shows another option that includes rule configuration – this is where the fluent api really helps out. After you add the rule to the ValidationContext, you are ready to start configuring the specified rule using a set of methods that are prefixed by “With”.

image

Custom Business Rules

There will be situations where you need to create a custom business rules. The Vergosity Framework contains the framework classes for you to create simple or complex rules. We will show you how to create these rules – and then use them in your code.

Simple Rule

Simple rules inherit from the Vergosity Framework class called Rule. You modify the constructor to send in your target. The Render() method is where you implement the rule’s validation logic. You will need set the IsValid property to true/false based on the rule logic – then, you will return a new Result object as show below.

Simple rules allow you create rules that can be used or composed into composite rules. The rule rendering using the ValidationContext is consistent whether the rule is a simple or composite rule. Therefore, you have a lot of flexibility in managing business rules for you business logic.

image

Composite Rule

You can create a custom rule that contains any of the default rules and/or other custom rules. This allows you to compose your custom rule to contain whatever rule-set you require for you business logic. The composite rule will inherit from the Vergosity Framework class called: RuleComposite. Creating a custom rule allows you to reuse the rule from one or more locations in your code. You are also encapsulating the rule implementation into a single rule – therefore, you will only have one place to modify or extend you rule implementation.

Building the rule set is similar to the previous example in the unit tests. However, in the actual rule, you use the Rules list to add rules.

image

The following is the code snippet from the composite rule class. If you have noticed the WithPriority setting, this allows you to set or arrange the order that the rules are evaluated.

this.Rules.WithStringIsNotEmptySpace(entity.Name)
    .WithName(“NameIsValid”)
    .WithMessage(“The name value is not valid.”)
    .WithPriority(100)
    .WithSeverity(Severity.Exception);

this.Rules.WithAreNotEqual(entity.DateOfBirth, new DateTime())
    .WithName(“DateIsInitialized”)
    .WithMessage(“Date contains the default DateTime value.”)
    .WithPriority(200)
    .WithSeverity(Severity.Exception);

this.Rules.WithRange(entity.FavoriteNumber, 1, 100)
    .WithName(“FavoriteNumberIsValid”)
    .WithMessage(string.Format(“The favorite number value is not within the specified range: {0}-{1}”, 1, 100))
    .WithPriority(300)
    .WithSeverity(Severity.Information);

this.Rules.WithGuidIsValid(entity.Id)
    .WithName(“IdIsValid”)
    .WithMessage(“The entity id is not valid. Cannot be empty Guid value.”);