Saturday, February 13, 2021

Strategy? My two cents on Design Patterns

This may seem a bit out of the blue. But I've been reading a bit on Design Patterns lately. 🤓 Even though there are plenty of materials out there on the topic, I still thought it was worth making a note out of. So here goes nothing.

For someone who have formally studied Computer Science, Design Patterns most probably must have been one of the first and foremost things to learn. For people like us, who came in to already vastly evolved computer science world, this might seem like just another theory, but thinking back to a time when these 'theories' didn't exist, it must have been really challenging developing rapidly growing and robust systems. 

Design Patterns, just like most of other theories in computer science, came to be from within the community itself. Developers, who encountered problems and found solutions in the systems they are developing, could see same thing happening all over again to fellow developers. They identified these common patterns that can be universally applied to similar systems and called them Design Patterns.

When it comes to software systems, we often have to think about objects, classes and relationships. We can apply design patterns to all of these aspects. We have patterns that takes object instantiation in to consideration, patterns that focus on class relationships and patterns that can be applied to object behaviors. Let's look at some famous design patterns divided into these categories.




One of the first design patterns I came across early in my carrier was the Strategy Pattern. Like most of us, I honestly did not expect to see the theories I studied being applied on live projects, and I was pleasantly surprised.😇 So I'm gonna make this post about this particular pattern.

Let me put forth the definition of the Strategy Pattern I studied way back in the good old university days here first. 👀

"The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it"

😕

I have no idea why these definitions have to be so hard to grasp, but this particular one is not so bad in my opinion. This simply implies that we can design a class, which uses some algorithm to do something, such that we can switch that algorithm without affecting the class itself. To give you an example, let's say we have a List class that has a 'sort' method. We should be able to switch the algorithm used in the sort method to any algorithm we want, be it the quick sort, the bubble sort or any other sort, without changing the List class. Sounds powerful, isn't it? Let's look at some UML Diagrams then.



Above diagram demonstrates how we can apply strategy pattern to the example I just gave. We can say that we have multiple sort 'strategies' or 'behaviors' or as per the definition, 'related algorithms' and we need to use them inter changeably in out list classes or 'clients' without changing any of them.

The List class above is the super class to all the list implementations which is denoted by the inheritance arrow. We call that relationship an 'is-a' relationship. LinkedList is-a List, ArrayList is-a List, so forth.  Where as the relationship between the List and the ISortStrategy is a 'has-a' relationship. In formal words, a Composition relationship. This is the relationship that makes it possible for us to switch the sorting algorithms as we see fit.

Let's say we want our ArrayList to have BubbleSort as it's sort method. Here's How we do this.

List arrayList = new ArrayList()
ISortStrategy bubbleSort = new BubbleSort()
arrayList.setSortStrategy(bubbleSort)
arrayList.performSort()  //will sort using  bubble sort


Now if we wanted to switch the algorithm to CustomSort, that's very easy to do.

ISortStrategy customSort = new CustomSort()
arrayList.setSortStrategy(customSort)
arrayList.performSort()  //will sort using  custom sort

See, we didn't have to do a single change to any of our List classes. Plus it's easier to introduce new sort algorithms to our system. This is how powerful the Strategy Pattern is. ðŸ’¥

This went longer than I expected. So I'm gonna stop my rambling now. Well, in a gist, Strategy Pattern encourages Composition over Inheritance because, with inheritance, the systems tend to get too complicated and unmaintainable with rapidly growing systems. 

Finally I want to introduce this amazing book I'm reading on Design Patterns, "Head First Design Patterns". I've never been more enthusiastic about a theory book until I got my hands on this one. Really cool writing style, as the title says, "A Brain Friendly Guide". KUDOS to the Authors!

See you in another post!


Link to the Book



Tuesday, January 19, 2021

Email Templates , the good, the bad, the worst! - Lessons learned

 I recently had to work on redesigning some email templates, and as usual, encountered some bumps along the way. So thought of making a note to myself as well as to the community while resurrecting this old blog of mine. So here we go.

In summery here are some dos and don'ts which I will explain in detail later in the post.

Always try to chose,

  • <table> over <div>
  • Hex color codes over RGB
  • Pixel dimensions over relative ones(such as %, em, rem)
  • Web safe fonts over web fonts
  • Inline styles over css class rules

 

Now lets get into the Whys 

 

Template Structure


While many email clients nowadays support rather modern html tags, there are still some clients which don't. The <table> tag being one of the oldest html tags we can safely assume all the clients to date support it. 

Special Tip: Use <table> as the wrapper element of the email content and any inner structures that need fixed relative width. This is because some clients are cutting out the body tag, so this wrapper becomes the container for the entire template. Wrap the entire layout in a single table instead of having multiple tables in the body. This is because when there are multiple tables with different sizes, mobile email clients scale them separately to fit mobile screens which might distort the original intended layout.

 

 Here's how I ended up with my template structure.

 


 Sizing

Limit the width of the layout to 600-800px. Specify width, max-width and min-width values of outer elements and use % widths for inner elements if necessary. For images, specify both width and height, don’t give auto height if not intended.

 

Spacing and alignment 

 

Better to use px to specify spacing(padding, margin etc) than relative measures because they highly depend on device dpi and the email client's interpretation of it. Don’t use flex or flex-box layouts. Control positioning with table elements instead.  For tables, (at least outer once) set border, cellpadding, cellspacing to 0 and use padding/margin to maintain proper distances. Use align to align content within table cells. 


Styling 

 

Some mail clients cut out <style> tags. Use inline styles(additionally).


Fonts 
 
Try to use web safe fonts and if web fonts are a must, use similar web safe fonts as fallback fonts. Don’t use shorthand css “font” when specifying fonts, use “font-family”, “font-size” etc instead. Use px for font sizes, the baseline for em can be different for email clients.
Below is a list of email clients with their support for web fonts.So that's about it generally for any email template design. (Source: https://helpx.adobe.com/si/fonts/using/html-email.ug.html)
 
 
 
Below is a small tip for Django developers(like me) regarding translation tags in email templates.
 

Additionally, Translations(Django): Try to minimize html elements inside translation tags(specially be careful with blocktranslation tags). And if cannot be avoided, keep the style/css out of them. This is to keep style changes from affecting the translations.

 

Happy 2021! See you in another post.