Source: https://www.cs.cmu.edu/~aldrich/courses/15-214-11fa/slides/11-design-patterns.pdf