On Team Productivity and Performance – Establishing a Nomenclature or Glossary

Before we reach adulthood, we learn how to communicate. Although communication can take the form of written or verbal, a common denominator is the establishment of a nomenclature or set of terms we all agree upon. That is the essential ingredient to any formal language. And all formal languages have a dictionary or glossary of these common terms which is often a living document improved over time.

So my readers, what makes technology so different? Why do we start numerous technical efforts without taking the time to formally define a key set of term even after we have a reasonable understanding of the problem domain? I suspect that if we take the time to do this, communication on a technology solution becomes far more reaching, less frictional and possibly more accepting across the board. These key attributes of your message will also foster a more participatory audience which is further advantageous for adoption and communication of your solution which hopes to address the needs of key stakeholders.

For example, I was fortunate to work with a cool piece of technology called Zeebe sometime in 2020. Zeebe is a piece of software which you can incorporate in your technology solutions to orchestrate business workflows.

Orchestration in this context refers to a mechanism to drive a workflow from start to finish. A workflow in this context is a defined sequence of distinct steps representing a certain business logic or business flow. Workflow examples include:

  • Placing an order
  • Purchasing a product
  • Making a payment
  • Starting a zoom call
  • Checking in a patient into a clinical portal
  • Authenticating a user into a system
  • Triggering a search and rescue incident

While working through a PoC which involved Zeebe, I found the documentation and technical conversations within the chat rooms and forums confusing mostly due to a misalignment of terminology and a lack of concrete definitions for each key system component or characteristic. We ended up putting together a Glossary which helped reduce confusion and also gave contributors of the document anopportunity to think about the underlying purpose of each key word and how it fits into the bigger picture.

Over my career, I have run into several of such similar situations where technical solutions, while brilliant, are not easy to communicate across a broader audience simply because engineers did not take the time to formalize a common set of terms. Without this common set of terms, we are leaving open to interpretation the single purpose of each key system part or characteristic which is usually an underlying contributor to miscommunication.

For example, terms such as workflow, device, application, service, client, partition, cluster, context can and will mean different things in different business processes. Therefore, before engaging an audience in any meaningful amount of technical discourse around a technical solution,

It is essential to first establish and agree upon a definition of common key terms before engaging

Klaus Nji

You either agree on these key terms or you ensure clarity in terminology inline as we have attempted to do in this document.

This would ensure alignment on an initial frame of reference for you and your audience. Once you have done this, the task of delivering your message through the software you write or technical documentation your author becomes more straightforward and gives you the luxury to inject color while, keeping you and your audience engaged, entertained and educated.

Happy New Year in Advance, Happy Coding and Happy Teaching and Stay Safe.

Software Patterns and Philosophies: Usage of a container facade

The problem

I was working with a relational data model which we denomarlized to be stored in Elasticsearch for searching purposes. While implementing a mechanism to stream changes from the underlying data sources into Elasticsearch, we had some choices to make on the underlying persistence.

While creating a POC to validate some assumptions, I found myself with a class, let’s call this thing a master builder, taking too many dependencies into its constructor like this:

        public class IdentityModelBuilder : CompositeModelBuilder<Identity>
    {
        private readonly IIdentityRepository _identityRepository;
        private readonly ISourceRepository _sourceRepository;
        private readonly IAccountRepository _accountRepository;
        private readonly IAccessProfileRepository _accessProfileRepository;
        private readonly IIdentityProfileRepository _identityProfileRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IEntitlementRepository _entitlementRepository;
        private readonly ITagsRepository _tagsRepository;
        private readonly IApplicationRepository _applicationRepository;
        private readonly IGovernanceGroupRepository _governanceGroupRepository;
        private readonly IAttributesRepository _attributesRepository;

        public IdentityModelBuilder(
            ISourceRepository sourceRepository,
            IAccountRepository accountRepository,
            IIdentityRepository identityRepository,
            IIdentityProfileRepository identityProfileRepository,
            IAccessProfileRepository accessProfileRepository,
            IRoleRepository roleRepository,
            IEntitlementRepository entitlementRepository,
            ITagsRepository tagsRepository,
            IApplicationRepository applicationRepository,
            IGovernanceGroupRepository governanceGroupRepository = null,
            IAttributesRepository attributesRepository = null)
        {
            _sourceRepository = sourceRepository;
            _identityRepository = identityRepository;
            _identityProfileRepository = identityProfileRepository;
            _accountRepository = accountRepository;
            _accessProfileRepository = accessProfileRepository;
            _roleRepository = roleRepository;
            _entitlementRepository = entitlementRepository;
            _tagsRepository = tagsRepository;
            _applicationRepository = applicationRepository;
            _governanceGroupRepository = governanceGroupRepository;
            _attributesRepository = attributesRepository;
        }

      //.. 
        protected override IList<IPropertyAssigner> EstablishSubContractors()
        {
            return new List<IPropertyAssigner>
            {
                new SourceAssigner(_sourceRepository),
                new IdentityProfileSummaryAssigner(_identityProfileRepository),
                new ManagerSummaryAssigner(_identityRepository),
               
                // ... omitted for brevity
            };
        }
    }
}

Usage of all these dependencies is not a concern as we are mostly delegating construction of parts of the Identity model to these subcontractors (assigners). However, the constructor makes me cringe, as it appears to violate certain aspects of the SOLID principles and also makes it difficult to use this builder within a context where we do not have all these dependencies: users will also have to modify their constructors to depend on all these artifacts. And this just propagates upstream!

The Solution

While I believe on passing dependencies explicitly from a code readability and testability perspective (not a fan of private member injection), this is one area where I believe one can leverage a construct such as a container facade to pass in these dependencies as follows:

   public IdentityModelBuilder(IContainerFacade containerFacade) : this (
            containerFacade.Resolve<ISourceRepository>(),
            containerFacade.Resolve<IAccountRepository>(),
            containerFacade.Resolve<IIdentityRepository>(),
            containerFacade.Resolve<IIdentityProfileRepository>(),
            containerFacade.Resolve<IAccessProfileRepository>(),
            containerFacade.Resolve<IRoleRepository>(),
            containerFacade.Resolve<IEntitlementRepository>(),
            containerFacade.Resolve<ITagsRepository>(),
            containerFacade.Resolve<IApplicationRepository>(),
            containerFacade.Resolve<IGovernanceGroupRepository>())
        {
        }

// second constructor omitted for brevity

Where the container interface is:

  public interface IContainerFacade
    {
        T Resolve<T>();
    }

This simple change allows one to use master builder in a context where do you do not have all those dependencies but do have access to the IContainerFacade.