Vukoje.NET

blog about software development

Naming is the design

There are only two hard things in Computer Science: cache invalidation and naming things. - Phil Karlton

Yes, naming is hard but it is also very important. We tend to think that big complex architecture is the software design and that type and member naming along the way is just something that is hard and that we screw up. My point here is that naming is the software design and that on daily basis to me it is more important than architecture.

If naming is good:

  • it will be easier to understand the code and get the big picture
  • API will be simpler to user and there will be less bugs
  • there will be a greater chance that code for some new feature goes to the right place and that software will evolve gracefully instead of becoming a big ball of mud

In book Domain Driven Design, Eric Evans describes the term Ubiquitous language for the practice of building up a common, rigorous language between developer and users, and we can think of this as naming on steroids. Also Obfuscation can demonstrate the importance of naming because obfuscated code has worst possible names so that is almost not human readable.

Naming and Cohesion

 

As applied to object-oriented programming, if the methods that serve the given class tend to be similar in many aspects, then the class is said to have high cohesion. In a highly cohesive system, code readability and the likelihood of reuse is increased, while complexity is kept manageable. - Cohesion

IMO types that have high cohesion are easy to name. Low cohesion types are hard for naming because usually they are schizophrenic and do many (unrelated things). So we can think of a good name as a necessity that will force good design decisions. 

Code example

 

I want to give an example of bad naming that irritated me enough to write this post. Here are some JavaScript DOM Event methods.

  • cancelable - Returns whether or not an event can have its default action prevented
  • preventDefault() - To cancel the event if it is cancelable, meaning that any default action normally taken by the implementation as a result of the event will not occur
  • defaultPrevented - Returns a boolean indicating whether or not event.preventDefault() was called on the event.
  • bubbles - Returns whether or not an event is a bubbling event
  • stopPropagation() - To prevent further propagation of an event during event flow
  • cancelBubble - Indicates if event bubbling for this event has been canceled or not.

For me it is hard to remember names of function and properties because they are not consistent. Here are some terms that are used interchangeable in API but mean the same thing:

  • stop, cancel, prevent
  • bubble, propagation
  • cancelable, hasDefault

Below is my proposal for renaming this API that should be trivial to remember.

Old New
cancelable hasDefault
preventDefault() cancelDefault()
defaultPrevented isDefaultCanceled
bubbles bubbles
stopPropagation() cancelBubling()
cancelBubble isBublingCanceled

Thoughts on logger lib design

Last year I gave a talk State of the art logging where I discussed logging, logging libraries and tools for logs analysis. I wanted to go a step back and share with you my notes on designing a logging library. I actually written down what was important for me and later decided to go with custom logger implementation that wraps NLog.

When I talk about logging I always tell a difference between tracing and event logging. By tracing I mean logs with high detail data useful for debugging app. Trace is available only in “tracing mode” – trace data is not collected by default. By event logging I mean data that application outputs to some persistent store and which are used for monitoring application behavior (e.g. crash reports).

 

Tracing

Tracing must have high performance:

  • It should have no performance impact if not turned on
  • String formatting should not be done if tracing is turned on (Tracing client code never formats string because formatting consumes time and it might not be needed)
  • It should have very small memory consumption when tracing is turned off.
  • When turned on it must not endanger app pool execution (e.g. production tracing must not cause out of memory exception).

Tracing should be enabled per session in web applications (multitenant or not) but should also work in cases where session doesn’t exist (tracing win services, tracing web applications before session initialization).

Tracing should support priority levels and labels (categories).

Tracing should support “Start – End” style logs with using statement. This will make tracing API better (smaller and more readable code) and make performance monitoring easier (time of method execution). It should also enable hierarchy displaying of trace data (similar to Call stacks in debugging).

If Tracing component uses external components this must be hidden (our trace will wrap them) because otherwise it would introduce high coupling to that external component and make any changes very hard.

Trace should support logging to file. File system organization for web multitenant applications should be like this: Root folder/tenant name/user name/date/request time stamp.log Programmer should be able to configure simpler folder structure in simpler cases (Windows service that doesn’t have tenant or user). Root folder should be configurable. If session is not yet initialized or is lost, files should be logged to Root folder/tenant name/.

In web applications it should be possible to trace each web request in separate trace file. In other cases programmer should be able to decide when to split file (per day, month, never…).

Trace should have buffer of last N relevant trace calls (probably only logs with highest priority). N constant should be possible to configure by programmers. Beside this buffer of last N relevant logs we might keep full trace of last HTTP request. This can be useful when tracing is not turned on and application breaks. In this case we might still want full trace form request that broke the app. This solution might compromise memory so we must be careful with it.

Trace files older by some period should be deleted in some time intervals.

Tracing must not break in production! Breaking is only ok in debug mode. E.g. if programmer supplies trace with invalid parameters, Trace should break only in debug mode.

 

Event logging

Event log should contain information about events in application that are of interest to people monitoring application health and configuration status.

Event log should support Event log types:

  • Breaking error
  • Handled error
  • Info
  • Warning

It should be possible to search and filer event log data. E.g. show me today’s breaking errors or show me yesterday information containing text “salesforce.com sync started”.

Event logs should contain enough useful data for understanding event details. E.g. braking errors should contain following data:

  • User name or logged in user
  • Application name (multiple applications might be logging events to same DB)
  • Exception data (call stack…)
  • Http request data
  • Trace buffer (what did User do before error – useful for extracting reproduction steps)

Events should be logged to DB and files. Logging to file is needed for:

  • applications that don’t have DB
  • logging DB access errors (e.g. invalid DB connection string)

Event logging must not break in production! Breaking is only ok in debug mode. E.g. if event log DB is not accessible, Event logger should not break.

It would be nice to have feature where Event Logs can be updated by support team with comment (e.g. “Known issue”, “Bug 123 created”, ”Resolved”…).

Event logging should not be transactional. If Event is being logged in some outer transaction and that transaction is rolled back, the event is still logged.

My badass list of JavaScript resources

About a year ago I finally started learning JavaScript so I could build complex, fast and fancy client web app that relies on restful services. I was completely new to this subject so I basically needed to learn everything from scratch… the language, best practices, architecture…

So here are resources I used for learning and libraries that helped me along the way.

JavaScript basics

First the language and most popular lib – jQuery.

Knockout

Knockout is great lib for MVVM that does client rendering and data binding.

Bootstrap

Grate CSS framework with fancy controls that supports responsive UI.

Controls

Additional controls that integrate nicely with Bootstrap.

Libs

Don’t make me think–notes from book

In effort to teach myself more about web design I have read “Don’t make me think” by Steve Krug. I recommend the book to everyone interested in the same subject. This book seams as a good starting point and additionally it is small and is being read very fast. If you are planning to read this book maybe it is best to wait for the third edition that will be out soon. Update – third edition is out.

So here are my most important notes I am sharing so I can look them up later.

  • Webpage should probably have following elements that should be easy to spot:
    • Site ID/Logo and tagline – Indicates what site is this? It should be clickable and lead to home page.
    • Site Sections – Indicates what are the major sections of this site? Current sections should be highlighted.
    • Site Search – Especially important for users that prefer searching to browsing
    • Utilities – Less important common link like login, home, how to by…
    • Page name – Clearly informs user on what page are currently.
    • Local (contextual) navigation - Show what are user options on current page?
    • Breadcrumbs – Clearly explaining where user is in site hierarchy and offering easy way to go back to some upper level.
  • Home page is different from the rest of the site and it should be designed more like billboard or cover of the magazine. For some visitors home page will be only chance to leave good impression about your site.
  • Home page common elements:
    • Site ID/Logo and tagline
    • Site Sections – to give an overview of what site has to offer.
    • Site Search
    • Welcome blurb – short description of site that should be visible without scrolling.
    • Teases – hints of good site good stuff (top stories, hot deals, most popular pages…)
    • Timely content – like recent news/comments to signal that site is live and frequently updated.
    • Start here – It should be clear to user how to begin using the site (e.g. user registration)
  • Things that are related logically should be related visually
  • Make it obvious what is clickable.
  • Omit needles words. Design web pages for scanning, not reading.
  • Good design makes web site obvious to users and it doesn’t requires them to think too much how to use it.
  • Test usability of your site at least once a month.

Batched by default

Few weeks ago I was listening to a lecturer explaining how Salesforce works from programmer perspective. Among other things I have noted that SalesForce cares very much about their performance. They care so much that they have forbidden sequential access to the database. This is also why database access API are all designed to work with batches.

Few day ago I was writing MS SQL triggers for the first time after long time. Again I have noted that API for triggers is batched meaning that trigger is called only once after all rows in SQL statement are inserted/updated/deleted. Once trigger is called programmer can access virtual tables containing all altered rows. Off course alternative approach (not batched) would be to call trigger after each row update and this would lead to much poor performance.

Today I have analyzed some slow peace of code that is slow because it is sequentially loading many complex objects from database. At first there was a need to load only single complex object and that is what programmers implemented without support for batching (loading multiple objects at once). Once there was a need to load more objects programmers again did simplest thing - they just run single loader in a loop. Both choices sound logical to me but they lead to some slow peace of code that won’t be optimized without significant effort.

This lead me to thought that all APIs should be batched by default. This will lead to faster code and just slightly less convenient API in cases where we work with one object.

 

Update:

My friend Andrija Cacanović reminded me that JQuery’s fluent API is nice example of batched API.

 

Sinergija 2013 presentation material

You can download (852.96 kb) or view online power point file from my Sate of the art logging presentation.

Below is video demonstrating Webcom GUI for log analysis and system monitoring.

Here is source code of other presentation demo that uses Glimpse, NLog, Autofac, Castle Dynamic Proxies and some of my NLog extensions to demonstrate some cool stuff. Remember to restore NuGet packages if Visual Studio doesn’t do so on build.

Here are some more useful resources used for presentation:

 

Speaking at Sinergija 2013

SinergijaLogo

I will be speaking at this year’s Sinergija.

Presentation is titled State of the art logging and here are my incomplete notes for it:

  • How to build state of the art production system instrumenting so you can easily understand what is going on in your production system?
  • Which component to use? Log4Net, NLog, System.Trace, custom solution…
  • Event vs. Trace (Monitoring vs. Performance)
  • Negative events
  • Tracing steps with “using” notation (e.g. MiniProfiler)
  • AOP vs. manual logging
  • Where to output data?
  • How to scope data?
  • How not to kill app performance?
  • How to bake in app profiler in your tracing lib?
  • Demo of Webcom powerful GUI for trace analytics system.
  • Demo of AOP logging in MVC web app using NLog.

Goodbye Soprex

Few months ago I have left Soprex and joined Webcom. I have been working in Soprex  for more than 5 years and in those years I worked with some amazing people with whom I built some amazing apps I’m proud of:

  • B5 (Big Five) - Multi-portal web application that hosts multiple sites with following major features: ePortal, eCatalogue, eShop and eStock. EPortal is CMS system that can host multiple sites which can share pages. ECatalogue allows web portals to expose Product catalog to site visitors. ECatalogue also allows product and product groups sharing among web portals. EShop allows site visitors to order products which availability is maintained through eStock.
  • Soprex Core Applicaton (SCA) - Framework for building enterprise applications written in .NET. Among many things it includes implementation of domain objects, micro-ORM, code profiler, custom MVP implementation that can run Windows and Web applications.
  • Price and Quotation (P&Q) - Application for Quoting and Ordering built for SKF’s distributor network. Application is based on SCA and includes identical Windows and Web GUI. P&Q implements very complex pricing business rules that on the other hand allow user maximum flexibility in creating offers for customers.

 

Below is photo of my favorite moment in career when our customer form Germany sent us cookies to express its gratitude for all the hard work we did for them.

01122011101

Love you guys… make tons of money and give me some of it :D