2/11/2021

To THIS or not to THIS

A classes methods can often reference its instance state or accept values as parameters. When should we use one technique vs the other?

If you think of an object lifecycle as starting, control, transformation methods. Constructors for starting, all public methods are control methods and private may be transformation methods.

Principle: Encourage pure functions, discourage object state.

Rule 1:

If the method it initializing an object then reference the object properties. 

func (x X) init() { x.foo = 1 }

Rule 2:

If the method is coordinating a request to the object then use the object properties. All methods that coordinate the operations performed on state are control methods.
func (x X) Control() { makeAChange(x.foo); return x.foo }
Rule 3:

If the method is changing an objects state only use parameters. Methods that change state should be simple to test and lend themselves to refactoring to other classes. These are usually private methods.
func (_ X) makeAChange(foo) { return foo + 1 }

4/08/2018

Catch Exception is Evil, Except When Required

Never write "catch (Exception e)" unless you can enumerate the reasons why it is acceptable.

A try catch allows us to intercept situations in our code flow that occur somewhere down a call stack. Generally associated with exception flow but not restricted to that concept.

Primarily talking to C# (or Java) Exception semantics but applicable to other languages to different degrees. An exception is a class that inherits from a based Exception allowing it to be "thrown" for later "catching" higher up the call stack.

The "System.Exception ("java.lang.Exception") represent the top of a hierarchy under which all exception types must be declared.

So this is where the problem starts. The following code is evil and should never be used unless you understand what the exceptions are (pun intended).

try {
  // do something useful
}
catch (Exception e) {
  // react to problem
}
Because the class Exception exists at the top of the hierarchy all exception types created for the application or system types will be caught. For example, a catch Exception will intercept a NullReferenceException (NullPointerException) what should only occur for a coding bug and never in normal production flows. All exception flows should be handled intentionally using the specific thrown class only.

One of our goals as programmers is to ensure we see all coding problems early in the coding process leaving only intentionally handled problems to show up in production. Hiding coding problems leads to production systems that blindly fail without any repercussions.

So why would you use this construct?

Control Loops

If you are writing code that exists in a root of an application, like something in a Main method, that is expected to handle all the situations that occur in a running process, then a catch Exception might be warranted.
    static void Main(string[] args) {
      var count = 2;
      var running = true;
      while (running) {
        try {
          Console.WriteLine("Hello World " + count);
          if (count-- == 0) running = false;
        }
        catch (Exception e) {
          Console.WriteLine("Unexpected error: {0}", e.Message);
        }
      }
    }
These kinds of constructs would want to control situations like unexpected exceptions and log them for review. An exception that is not caught and ends up being thrown to the runtime may only be reported to standard out and perhaps be lost to anyone trying to determine why a program crashed.

Framework Isolation

If you are developing an application that expects to load and run a dynamically loaded 3rd party library then you will want to isolate the management of all interactions with that library. These are interactions you can not test for so protective steps are necessary to ensure predictable outcomes.
try {
  var dll = Assembly.LoadFile("hello.dll");
  foreach (Type type in dll.GetExportedTypes()) {
    var hello = Activator.CreateInstance(type);
    type.InvokeMember("World", BindingFlags.InvokeMethod, null, hello, new object[]);
  }
}
catch (Exception e) {
  Console.WriteLine("The DLL shouldn't have done that");
}
In this manner all interactions will protect the management program and allow for positive feedback to the user or developer of the dynamic library.

Thread Entry Points

The final situation that might require a catch Exception occurs when starting a background thread that throws an exception. For similar reason to catching in a control loop, the threads stack is started at a method specified at launch time and any thrown exception flows up to the runtime in the context of the thread, never returning to the launching thread.

So, if you spawn a thread and want exceptions handled in a specific manner then a catch Exception might be warranted. DotNet and Java runtimes swallow any exception from a background thread only reporting them to standard out so they may be missed during development and certainly not logged in a normal production configuration.
try {
  new Thread(MyThread).Start();
}
catch (Exception e) {
  // This will not catch the threads exception.
}

public static void MyThread() {
    try {
      throw new Exception("Thrown in threads");
    }
    catch (Exception e) {
      Console.WriteLine("Threads should report their exceptions");
    }
}
This means that all thread starting code should wrap thread entry points in a simple management method to ensure consistent exception handling throughout the application.

Common Arguments

These basic rules are ignored for a few reasons. The most common is "I do not know what exceptions might be thrown so catch Exception makes my code safer". To begin with, it is the responsibility of a programmer to know what their code is doing, so "I don't know" is never the right answer. Secondly, you must test drive all possible outcomes from your codebase, which ensures you will know what can be thrown. Additionally, if you miss one, you want it to be made very obvious so that you can fix it as soon as possible instead of failing secretly.

Another concern is that processes should never crash in production. Unfortunately, when the catch Exception solution is used for this it also means processes ever crash in development. So instead of ensuring your program works because you intentionally designed it that way, it only secretly says up in a failing state like some diseased animal hobbling through the woods.


The last excuse excuses the practice of using catch Exceptions offering that each must result in a log message so that the problems can be fixed. This results in volumes of log messages and the inevitable conversations that start "Oh, that exception is expected, don't worry about it" as all the critical log messages are lost amongst the chaos.

If you are making these arguments today, I suggest amending your ways.

May your exceptions be intentional and your reactions true.



1/15/2016

Team Culture - Belief

We know that teams need to see the future and feel part of its creation. We talk to roadmaps and share in decisions that re-enforce our shared understanding.

However, we spend a lot of time "doing" because we think we have to. Teams only thrive when they understand the future and become part of creating it.

  • We want people to act as they believe.
  • We want people to act because they believe.
  • We want people to listen and learn because they know there is more than they know.
Don't follow when there is an opportunity to understand and share the lead.

all the leaders



Be willing to argue
Be willing to fail
Be willing to champion
Be willing to learn
Be an advocate of our shared intent.







Coalescing free, individual opinions into a shared opinion is what good teams do.

11/11/2015

Agile vs Rigidity.

I think we humans have a problem expressing decent without recognizing existing value.

A system with invented boundaries, requires that people decent when the boundaries are breached.

A system with intentional boundaries requires that those boundaries are challenged.

The evolution of a flexible system is an interplay between the intentional rigidity of good rules and the intentional experimentation of alternatives.

Breaching boundaries is the clue that we are assessing the current rules.

Limiting change is not rigidity, it is the siting of theories that describe optimal flow, each of which requires proofs.




3/07/2015

Who Prioritizes Agile Stories. Ops, Security, Devs or the Business?

The problem is an old one; who decides what a development team should focus on next. Traditionally, we say "the business" but we know that product quality and technical debt can loose out. When does "the business" consider security important? Unfortunately, in todays tech world, security is consistently an afterthought.

I believe I have a solution, which stems from trying to understand the question. "Who decides the priority of a story" is the wrong question. It obviously depends on the story. Agile teams profess working together for a common goal, all skills sharing ideas, planning and implementing together, but we never said that everyone on the team knows everything or is skilled or knowledgable enough to make all decisions. Hence the team thing.

So the answer is "Allow prioritization within skill scope" or said more verbosely, "People with specific skill sets make prioritization decisions related to the scope of their skills and goals".

At the end of the day, everyone in the company wants the same thing. Lets make some money, using quality products that are stable and support the services the business sells all the time, and no one wants our products to be exposed to attack.

Story priorities must be defined in this sequence:

1) Production Operations Team

At the top of the list are stories written by the Production Operations Team. These people know how the products they watch over run and are solely responsible for the day to day stability of these products.

Since all businesses want to maintain the services they are selling, it makes sense that a story addressing a problem in this scope must be prioritized first.

An example might be, the automation of a task that results in errors when performed manually. The removal of pageable errors from log files that have no corrective action. A product deployment process that minimizes over night work.

The impact of a problem that this team faces must be reviewed by everyone, but as soon as it impacts this teams ability to operate the products, then they get first dibs at priority list.

2) Security

Next on the list, a security team is responsible for the monitoring, response to attacks and verification that the development teams are building secure products. Any action that detracts from these goals must be prioritized above anything else since it is core to the businesses desire to protect their customers.

A Security Team is responsible for evaluating risk/reward against all possible attacks, but once a protection is deemed needed it gets into the next sprint, right behind any outstanding Production Operations stories.

An example might be, add validation to a field to prevent an injection attack. Integrate a static analysis tool into the CI build to invest in continuous verification of code.

3) Development Team

A development team is responsible for the building and delivering of quality products to production. They are responsible for ensuring they can perform their duties fast and efficiently and with zero defects.

To address this responsibility the Development Team must write stories that address items that might jeopardize their success. It is within their rights to define how they can best achieve the goals of the team.

An example might be, remove duplicate code to eliminate potential bugs. Implement a test framework that will ensure the code always works. Re-write a legacy code module that continues to introduce bugs to the product and slows down feature delivery.

The Development Team also wants to deliver quality features as fast as possible so is responsible about how they asses the risk/reward of changes.


4) The Business

Does it seem strange that the lowest priority group to set priorities is The Business? This was a revelation to me. I thought of it in a tribe retrospective a few weeks ago, when someone asked  a simple question, "Why did we let ourselves create this problem"?

The phrase "The Business" is mis-used of coarse. A company has many departments performing functions that sustain happy customers. IT is one of those departments and is therefore also "The Business". The mixture of skill sets hired by a company including, accounting, purchasing, HR, and programmers, all allow the business to achieve its goals and make money.

So, lets state it this way, if a department in the business needs some changes in a product, then various skills will be involved to achieve that; IT, support organizations, BI groups, operations teams, sales and marketing, training and the list goes on. To make a change to an established product, lots of stuff has to happen and all those teams are responsible for performing their duties to best achieve the companies goals.

Planning that change and prioritizing it against all the other changes from all the departments is part of the business benefit evaluation that occurs to produce road maps.

In the end, that change, written out as a set of stories, optimized for MVP, and evaluated by the development teams to maintain the road map, gets slotted in to the list of stories that the team must work on.

Fear

I hear you say this is crazy. The business pays me and can fire me? What if the developers decide to take 6 months to make the code pretty, you know how much they want to get rid of all those tabs and it takes them so long to get anything done as it is?

Trust between groups is always a challenge. Different people with different skills and different goals will never completely understand each other so mis-trust is easy. However, people are a companies most powerful asset, so fix that first, and allow them to thrive together.

Conclusion

The most efficient way to move forward is to optimize how each team works. Let the developers prove they can deliver features fast. Let security make our customers safe by allowing them to drive how these products should protect them. Let operations teams sleep well because they know how to optimize their work. With these goals, all "Business" changes will be delivered fast and without question.