All posts by visionarycoder

12 Factor Apps vs The Method

Red Hat dropped an article on 12 Factor Apps. Go take a look at that first. An illustrated guide to 12 Factor Apps | Enable Architect (redhat.com)

Now, download “The Method” from iDesign. Transform your software architect career (idesign.net) Filter: “Other” Look for “The IDesign Method.”

Perspective

Reading through the 12 Factor App article, I see huge overlap with what Juval has been advocating for decades. Lots of this material is directly stated or covered in the onsite training for “The Method.” 

Slicing apart components on the boundaries defined in the method takes cares of a large percentage of the suggestions. 

Hiding data resources behind an accessor decouples persistence. 

All cross-cutting concerns should be treated as utilities, shared by all components in the development stack. Message brokers are infrastructure services either baked into the host platform or run as a utility.

The Method foreshadows everything in the 12 Factor App, with the possible exception of a single code repository. I don’t want to rabbit hole on this idea but why does your app have to use a single code repository? There are legitimate reasons to avoid this approach: legal; geography; network isolation/latency; etc.

Services

In the language design community, there is a push to make everything a service. Reference types and Value types can be services. The service could tell you the stored value, when it was updated/created, provide methods for manipulation, or any number of other things.  There is no reason why we can’t do this. It’s already symbolically implemented in the Actor pattern.

Events

Next, consider all communication as events.  Calling a method is an event.  Writing to disk is an event.  Turning on an LED is an event.  Something “happens” therefore it is an event.  

Baseline

Every value object is a service.

Every communication is an event.

How does this apply to 12 Factor and The Method?

The Argument

I’m going to pick only on Point 11 of the 12 Factors to show how the Method is embedded in the 12 factor approach. If anything, it give guidance on how to actually deliver on the 12 factor app schema.

Treat logs as streams of events. 

Why should this just be logs?  Why are logs special in the larger application design? Honestly, they are not special.

All communications between objects are events. A “logging” event has a payload to describe the event. The event is posted to a channel where event subscribers can process the the event payload as needed. This is the exact same interaction model as a WCF channel managing RPC calls from a manager method to an interface implementation across component boundaries. This is all described in The Method.

Don’t get distracted by the details of the communication. The platform should make those details transparent to the developer. It doesn’t really matter if you use REST, Pub/Sub or Queues. All of these have cost/benefit ratios to figure out for your project.

For me, the important part is seeing how Juval’s ideas predate 12 Factor Apps.

Returning to logs.

If everything thing is an event why do we need a specialized logging model?  We don’t!

All events fire across one of more channels. Symbolically, a log event is the same as an event requesting an action from another component. The subscribers to that log event can write the events: to a tiny debugging log inside the component context; an application level log on the device; a sql data store for security authentication; non-sql data lake for later analysis.

In conclusion

Do you see the possibilities with this approach?

Spend some time reviewing the 2 articles. Look at the 12 Factor diagrams, turn them sideways and see how Juval showed these same ideas over a decade ago.

Code Smells

At times it can be a challenge to figure out what’s wrong with an application or component. It’s just a nagging feeling in the back of your mind that something isn’t quite right.

For me, that’s a code smell.

Here are a few that I try to keep an eye out for and avoid at all costs in my development efforts.

  • Rigidity
  • Fragility
  • Immobility
  • Viscosity
  • Needless Complexity
  • Needless Repetition
  • Opacity

I strive for SOLID and DRY. Anything that violates those principles needs to be reviewed. Single-responsibility principle and Liskov substitution principle are biggies for me. Do one thing and do it really well. Wrap everything in an interface. Implementation details should always be hidden behind that interface.

The Purge

Recently, I moved around my Azure subscription. The site was down for a while and that was fine. I got everything spun back up, got everything updated and life was good. Eventually, I started poking around my site fixing broken links, removing unused templates, and the like. Along the way, I realized I have over 5,000 subscribers. None have ever posted a comment. Probably because I block all spam comments.

This got me thinking and purging… I removed all @*.ru subs. I started to see naming patterns, patterns that were obviously to human eyes but not machine eyes.

So…

I’m dropping all subscribers that don’t have an avatar. If you think I dropped you and you still want to subscribe, please re-up. I am also adding 2-factor authentication which should help limits bots from setting up more of these bogus accounts.

Anti-Patterns with CONSTANTS.

I have a habit that’s probably an anti-pattern. I like to nest classes in a constants file.

  1. I always call the file Constant.cs. Singular. It goes at the root level of my Framework project. This should be accessable from every other project within your solution.
  2. The class is a static. Therefore, all of the subclasses are static as well.

Normal Constant file

public static class Constant
{
  public const string Title = "My Title";
  public const string EmailAddress = "foo@bar.com";
 }

Now consider this…

Nested classes

public static class Constant
    {
 
        public const string Title = "My Title";
        public const string EmailAddress = "foo@bar.com";
 
        public static class Color
        {
            
            public static class White
            {
                public const string Name = "White";
                public const string HexCode = "#FFFFFF";
            }
 
            public static class Black
            {
                public const string Name = "Black";
                public const string HexCode = "#000000";
            }
 
        }
 
    }

Usage

public class Usage
    {
        public void Example()
        {
            var blackHexCode = Constant.Color.Black.HexCode;
        }
    }

I like how this creates a clean hierarchy to reference a constant. As I said, this is probably an anti-pattern. But it works for me.

Slippage

Ouch!

I hadn’t realized it had been so long since I posted. That said, I’ve been rather busy. Family stuff, work stuff, relocation/new house stuff, health issues, new motorcycle stuff, etc. Basically, life stuff.

I changed teams which required me to move back to Oregon full-time. Hence the relo/house issues. At this moment, I’m working on a mobile app team, doing Xamarin development for an internal app on Android and iOS target platforms. And I’m still keeping my toes in the Application Architecture team. They are going through some churn right now as Senior management realigns.

We have a new IT leader. I don’t remember if she is the CTO or CIO. It doesn’t really make any different from where I’m sitting. I like what she had to say in her first public forum. I heard pragmatism over dogma. I didn’t hear the whispers of highly paid consultants forcing unneeded changes if only to justify their presence. But… We’ll see how it goes.

So.

There has been a little slippage. I might even do something about it, but I need to heal up from my last surgery. Having already torn a couple internal stitches, I might actually take it easy for a week or two.

Generic Types with Complex Constraints

I am working on a WPF app, leveraging Prism and Unity.

I have a scenario where I have lots of similar views/viewmodel. Not exactly alike, but 90%. I have 22 dimension-type datatypes. Instead of building out 88 individual MVVM scenarios, I am doing a cut-n-paste for the 22 instance of each specific activity (CRUD/Navigation). I needed to figure out how to define a generic base viewmodel that enforced inheritance for the generic type.

BTW: This is a throw-away app with an expected <3yr lifespan. It’s not worth the time/effort in building up something truly dynamic. I need to slam it out and pass it off to off-shore support. If it’s too complicated, I won’t be able to hand it off. This falls under, ‘Just get it done,’

All of the samples I could find were ‘ClassName<T,U> where T : class where U class’ examples. That doesn’t work for what I need to do. Below is how I solved the class definition issue.

public class DimensionBase : BindableBase, IChangeTracking 
{
...
}
public abstract class CollectionViewModelBase<T> : BindableBase, INavigationAware, IActiveAware where T : DimensionBase 
{
...
}
public abstract class DetailViewModelBase<T> : BindableBase, INavigationAware where T : DimensionBase 
{
...
}
public abstract class EditViewModelBase<T> : BindableBase, INavigationAware, IConfirmNavigationRequest where T : DimensionBase 
{
...
}

What I learned is that you can tack on the where clause to the end of the class definition to enforce constraints on the ‘T’ after all of the constraints are applied to the base class itself. I had been trying to manage the ‘T’ constraints first which is following my understanding of the ‘standard’ examples of where T … where U …

The delete action is managed by the collection view model, by way of the confirmation dialog hosted in the shell. I use events to manage that process.

There one more thing I want to clarify. I am using the region manager to handle all view-based navigation. I am using the event aggregator for passing messages around the system. The biggest one is telling all of the views to refresh their data when the target environment has changed. Getting navigation/confirmation dialog to fire, leverages events because the views hosted by separate modules (24 so far) that cannot directly access the notification/clarification dialogs hosted in the shell. Nor does Prism enable hosting these dialogs in a region (as far as I can tell). So there is only one way to do it. Events.

Enjoy.

TED talk: Feminism

Well worth the time to watch.