Designing classes can be a challenge for even experienced programmers. In some situations, the design and use of classes is natural as it corresponds to real world applications. However, often classes do not correspond to real or natural entities, but require a high level of abstraction as well as anticipating uses and future changes. The effective design of classes often is a creative activity that requires imagination as well as an understanding of the underlying application. Even experienced programmers make poor decisions related to the design of classes and objects.
Software teams often spend considerable time and effort on such design decisions. After decades of practice, people developed many design patterns on how to effectively design and use classes and objects. The following website introduces common object-oriented design patterns: http://www.oodesign.com/.