Monday, January 31, 2022

The Zen of Coding - Separation of Concerns

Continuing with my series on the Zen of coding, meta rules that apply universally regardless of coding language or style in use, today I want to discuss Separation of Concerns. 

Separation of Concerns is a design principle for partitioning a system into discrete logical elements. Each part of the system should focus on a single concern, which is not shared with other parts of the system. The term Separation of Concerns was probably coined by Dijkstra in 1974. This principle applies at all levels of a system, from the conceptual and logical models, down to the physical level. Again here, as with Magic Numbers, the benefit of following this design principle at the code level is more readable, and hence more maintainable code. 

Robert Martin's Single Responsibility Principal, is another wording of the same design principle. When you properly separate concerns each component, class, or module has a single responsibility.

If you don't follow the principle of Separation of Concerns over time you end up with a monolithic design, which are harder to read, harder to refactor, and harder to maintain. The answer is of course to refactor when you find there is no longer a separation of concerns. This is just one more refactoring pattern that you should be applying daily as part your work. It is part of the reason why refactoring needs to be part of the daily development cycle and not a separate story or event

Separation of concerns applies at all levels of the design from the details of the code, to classes, as well as to how the system is partitioned into executable modules.

Separation of concerns strongly relate to the concepts of Coupling and CohesionCoupling and Cohesion are concerned with the degree of dependency within and between modules. We should always minimize dependencies between modules (Coupling), and we should be looking for high inter-relationship of functionality within a module (Cohesion). Module may be a class construct or something higher level. Again here, Separation of Concerns is going to lead to low Coupling and High Cohesion by keeping single concerns focused together and separate ones independent.

Zen of Coding Rule: Always separate concerns. 

Happy Coding.


Previous posts in this series:

Wednesday, January 12, 2022

The Zen of Coding - Magic Numbers

I have been coding professionally now for over 30 years in a large variety of languages. There are a number of practices that I have found to be universally best practices regardless of the programming language or programming style in use. Many of these relate to how readable code is, which is the 2nd most important aspect of code, right behind correctly functioning code.

Readable code is more easily maintained, and I have yet to run into the app that I didn't need to revisit and update. In general, code is read an order of magnitude more often than it is written. It is one of the reasons why coding style guidelines are important if there is more than one author working on a project, either concurrently or across time. With the growth of open source and more companies using agile teams, it is rarer and rarer to be the sole author on a project. 

The Zen of coding are these meta rules that apply universally. Many of these items are noted in other places on the internet and in books. You can look at this as my list of favorite coding pet peeves to avoid. Let's, start with the first one magic numbers.

What is a magic number?

A magic number is a literal numeric value in code, outside of a assignment of that value to a named constant. For example 22/7 in the following code is a magic number.

float circularArea radius * radius * 22/7;

Looking at this code, most people are not going to know what 22/7 is. A better way to write the code would be

float circularArea = radius * radius * Math.Pi;

Here we can use a predefined constant as opposed to defining one ourselves. Let's consider a program dealing with force and acceleration. When you find 9.8 sprinkled all over the code you might be able to deduce from the code that it is the value of gravitational acceleration. It would be much better to declare the constant and use the name of the constant everywhere else in the code. For example:

const float gravitationalAcceleration = 9.8;

Doing this not only increases the readability of the code, but also has the added benefit of increasing maintainability. When a more precise value for gravitational acceleration is needed, such as 9.80665, the code only needs to be changed in one place.

Some people have raised a concern that the extra assignment can affect performance. I have yet to run into the case where this is the case. I have gone so far as to prove this by looking at the compiled assembly language to prove it.

Zen of Coding Rule: Use constants whose name has semantic meaning instead of numeric literals. 

Happy Coding.

Tuesday, June 8, 2021

Working with JSON in Powershell - Collection of hashtables

Some time you interact with a rest API, which returns a block of json containing a collection of items that you want to enumerate over. If the collection of items is not in an array, but looks like the following, it is challenging to iterate over the collection.

{ "firstItem" : [ "one", "two" ], "next" : [ "yes", "no", "maybe" ], "6739" : [ "red", "blue", "green" ] }

Of course we could say that the author of the rest api should change the returned result to make it easier to interact with, but that is not always within our control.

In PowerShell we can make this collection enumerable with a few extra lines of code. 

If you are working with a newer version of PowerShell (version 6 or newer) you can use the -AsHashtable parameter to ConvertFrom-JSON

If that is not the case, you can still make the json response enumerable as shown below. 

$json = ... response from the api $data = $json | ConvertFrom-Json $enumerableData = $data.psobject.properties | Select-Object Name, Value foreach ($element in $enumerableData) { Write-host "$($element.Name)" foreach ($element in $element.Value) { Write-Host "`t$element" } }

The output from that is:
firstItem one two next yes no maybe 6739 red blue green
It is a nice little snippet that gets the job done.

Wednesday, January 13, 2021

PowerShell: Write-Output - What does it mean to pass objects along the pipeline

These days I spend a lot of time writing Terraform and PowerShell. There are many blogs about the difference between the various Write-xxx functions in PowerShell, Write-Host, Write-Verbose, Write-ErrorWrite-Output, etc. Many of these posts, such as Writing Output with PowerShellas well as the actual documentation mention that Write-Output passes objects along the pipeline. This has an interesting side effect if you use Write-Output inside of a function in PowerShell. Let's play with some code to see what I mean. 

Let's start with a simple function.


This works as expected, we see the two lines in the output. Now let's make one change when we call the function


One line of the output is missing. This is because Write-Output passes the object along the pipeline. 

What if the function returns something, for example an array of strings? Let's take a look at the code and results in Visual Studio Code. I am hard coding the array here for illustrative purposes, I originally ran into this when I was querying an API and returning results in an array.    



Notice the returned $val, as shown on the left, has three elements in the array. The third is the parameter passed to Write-Output. The type of that is System.Management.Automation.PSObject. 

The challenge I ran into when I found this was that I found the size of the Array in the calling function was larger than the size of the array in the called function. The fact that Write-Output writes objects to the pipeline means we should only be using it when we intend to process the resultant object in a pipeline. If not, I would stay away from Write-Output and choose one of the other variants. If you have a preference of which variant is better and why, I'd love to hear your opinion. 


Friday, June 26, 2020

Azure DevOps Server (TFS) Operational Intelligence Activity Log

There is a little known feature of Azure DevOps Server, at least the on-prem version, that allows admins to look at the requests made to the server as well as the activity of the JobAgent.

This feature can be accessed by pointing your browser to 
<Base Server URL>/_oi/_diagnostics/activityLog
for example:
https://TFSServer/tfs/_oi/_diagnostics/activityLog


Once there you can switch between two views the Activity log and Job Monitoring by clicking on the tabs on the left.



The activity log shows a list of the requests being made to the server, including the identity of the requestor, the source IP address as well as the HTTP Response Code. I have found this helpful in tracking down when people are having issues.






One of the other nice things is that the activity log is exportable to CSV (see the green highlight above, which makes it very easy to work with in MS Excel and drill down to see just a single requestor.

The Job Monitoring tab shows a number of graphs about the Job Agent, the internal worker process. The graphs are all clickable and drill down to further information. 

I don't access this operational Intelligence information very often, but when I need it, it is information I can't find anywhere else. Hope you find it useful as well


Wednesday, February 13, 2019

Passing variables by Reference in PowerShell

I often have to write PowerShell scripts that perform some operation on a set of files. Sometimes I need to validate something about the files, for example that they are all well formed XML. 

The requirements are that 
  1. All files are examined
  2. Any files that have an issue are called out
  3. The script returns a failure if one or more files fails the check.
To examine all of the files I use Get-ChildItem and then pipe that into a function to do the verification. 


Get-Childitem -path $directoryToCheck -filter '*.xml' -recurse | VerifyXMLFileFormat

and VerifyXMLFileFormat looks like



function VerifyXMLFileFormat {     foreach ($o in $input)     {         Write-host 'Reading:' $o.FullName
        try         {             [xml]$xml = Get-Content $o.FullName         }         catch         {             Write-Host "$($o.FullName) is not a valid XML file"         }     } }

The challenge I have run into is that I have been unable to easily set a value in the called function and use it outside of the function because of how it is called as part of a pipeline. If in the catch block I use Write-Host-Error, or return $false, or throw, then not all of the files are processed. 

What I wanted was to pass a variable by reference so that VerifyXMLFileFormat can set the value and the calling function can reference the value. To do that I had to add a [REF] and access the .Value of the variable like this in the function


        catch         {             Write-Host "$($o.FullName) is not a valid XML file"             $invalidFileFound.Value = $true         }

Now I call the function like this


[bool] $invalidFileFound = false
Get-Childitem -path $directoryToCheck -filter '*.xml' -recurse | VerifyXMLFileFormat ([REF]$invalideFileFound)

Using that I can now meet all three requirements that I had


Saturday, May 12, 2018

Can we avoid learned intuitiveness?

Learned intuitiveness, sounds like an oxymoron right? Learned intuitiveness is when you need to learn the general principles of how an interface works before it is intuitive (obvious) how to make it do what you want. In other words it is NOT automatically understood. Let's take a look at what Merriam Webster says about intuitiveness. There are two definitions that we should look at, the others are defined (in terms of intuitive)
  1. directly apprehended
  2. readily learned or understood
It is the later one that defines learned intuitiveness, it is easily understood, but perhaps not instantaneously. As an example of this, take an iPhone user and hand them and Android phone, or visa versa, and ask them to make a phone call. In my experience, unless one if familiar with both platforms, the user will fumble around trying to do what is natural for them on the platform they are used to because they learned that intuitiveness.
While this is wonderful for vendors because when users need to upgrade they will quite often stay with the platform they are familiar with due to their familiarity with it, they have learned the intuitiveness of that vendor's interface. In UX terms, upgrading to a new version of a platform should not break the users mental model
The question that I feel needs to be posed is do we need to rely on learned intuitiveness or can we build an interface that is automatically understood? I am not certain what the answer is and would love to hear your thoughts.





Software Craftsmanship — Why Testing Matters More Than Ever

A few weeks ago, I wrote a post called SoftwareCraftsmanship — When AI Writes the Code . The basic idea was pretty simple: AI hasn’t made so...