Yes, this blog has a double title. Every now and then you need to do a little self reflection. Two weeks ago I was in talking with my fellow PRS member Soren Klemmensen and we discussed the fact that in the list of object oriented Design Patterns that we brought to Dynamics NAV there are a few that could be built in or better integrated if Microsoft would help us a little.
Ok, if you read this and think, what does this guy mean, then I should tell you some background first, otherwise just skip this part.
For the last 4 or 5 years ago we have been working on the Design Patterns project. Next to documenting the existing patterns with Microsoft we also tried to look at some best practices to better code in Dynamics NAV. They are also design patterns, categoriesed as implementation patterns, meaning the way you structure code.
Examples of these patterns are:
- Class, Method, Property (aka Agents/Actions)
- Natural Language Programming
- Surrogate Keys
You can learn more about these patterns on my YouTube channel.
While most of these patterns have nice names now, we actually changed them quite a number of times. Natural Language Programming was once called Readable Code and Encapsulation was called Atomic Coding. The Class, Method Property has two names as well. Reason for this is that we learned during the project that most of these concepts are well known in computer science and object oriented programming. We were reinventing wheels.
Dynamics NAV has a realtively basic development environment that does not allow us to do things that Visual Studio and C# or other languages do. On the other hand it has lots of things that C# does not have that we can take advantage of.
This can come in handy when trying to make a couple of these PRS design patterns obsolete, smarter or built in the environment. One of the reasons we can do this is becuase C/AL and C/SIDE are very metadata driven.
So what patterns can be made obsolete
Class Method Property (aka Agents/Actions)
This pattern teaches us to make all functions that you can perform on a table a member of the table and if complex enough put inside their own codeunit.
The reason why we thought of that is actually a bug in the symbol menu. The symbol menu does not understand code outside the contect of the variable you define. For example: if you define a variable of the type Sales Header, it does not show that we have a codeunit that takes this record as a parameter and posts it.
If that would be the case, we would probably have to rethink this pattern. I have implemented this pattern at one of my solutions where we have a table that is more or less the core of an application. This table now had douzens and douzens of functions. I can honestly say that this does not improve usabilty more than loosely coupling the codeunits to tables.
It would be easier if NAV reads the metadata and helps with the symbol menu. That would save a lot of functions on the table that are then obsolete and actually a hassle to maintain.
This was the example I thought about yesterday when I did an introduction to design patterns workshop for NAVUG USA. I was talking about encapsulation and override. Most languages allow programmers to override functions in a class. NAV does not.
With PRS we found Facade as a solution for that, but it is actually wrong to suggest to implement a facade for each function you create on the table. Think about it. You would dramatically make your code more complex than required.
Facade is a great pattern! It exists in object oriented world and it should be implemented by design if the architect expects functional requirements to override the function. The typycal example is weighing bridges where every customer has their own hardware and has a custom interface. This is what facade does great.
C/AL should allow programmers to override any other function at design when required without the orriginal architect anticipating every move. Other programming languages allow that.
This is the newest member of the PRS design patterns and as most other patterns it started its life with another name. Unique Record Identifier.
In dynamics NAV most tables are connected through the primairy key, for example comments. Comment tables have complex primary keys to be able to connect them to each table in NAV.
The idea is to add a single unique key to each table in NAV so we can connect to other tables using a single unique key. Think about the possibilities to add factboxes using this to each table in NAV without thinking.
C/SIDE can add this automatically for us.
Some design patterns can be improved with what I think are relatively small changes to C/Side. We should always self reflect and realise that some things we do are actually workarounds.