👨‍💻
Software Engineering
Clean Code: Agile Software Craftsmanship
Clean Code: Agile Software Craftsmanship
  • Clean Code
  • 1: Clean Code
    • There Will Be Code
    • Bad Code
    • The Total Cost of Owning a Mess
    • Schools of Thought
    • We are Authors
    • The Boy Scout Rule
    • Prequel and Principles
    • Conclusion
  • 2: Meaningful Names
  • 3: Functions
  • 4: Comments
  • 5: Formatting
  • 6: Objects and Data Structures
  • 7: Error Handling
  • 8: Boundaries
  • 9: Unit tests
  • 10: Classes
  • 12: Emergence
  • 13: Concurrency
    • Why Concurrency?
    • Challenges
    • Concurrency Defense Principles
    • Know Your Library
    • Know Your Execution Models
    • Beware Dependencies between Synchronized Methods
    • Keep Synchronized Sections Small
    • Writing Correct Shut-Down Code is Hard
    • Testing Threaded Code
    • Conclusion
Powered by GitBook
On this page
  • Class Organization
  • Encapsulation
  • Classes Should be Small
  • Single Responsibility Principle
  • Cohesion
  • Maintaining Cohesion Results in Many Small Classes
  • Organizing for Change
  • Isolating from Change

10: Classes

Class Organization

  1. Variables

    • Public static constants, if any, should come first.

    • Private static variables

    • Private instance variables

      • There is seldom a good reason to have a public variable.

  2. Functions

    1. Ordering should follow the ordering of variables.

Encapsulation

  • Utility functions should typically be private, but we're not fanatic about it.

  • Sometimes a variable or utility function needs to be protected so it can be accessed by a test. If a test in the same package needs to call a function or access a variable, we'll make it protected or package (internal) scope.

  • Loosening encapsulation should be a last resort.

Classes Should be Small

  • First Rule: Classes should be small! Second Rule: They should be smaller than that.

  • Function size is measured by counting lines. With classes, we count responsibilities.

  • Class names should describe the responsibilities it fulfills.

    • If this is difficult, the class may be too large.

    • The more ambiguous the class name, the more likely it has too many responsibilities.

    • Avoid weasel words: Processor, Manager, or Super

Single Responsibility Principle

SRP: A class or module should have one, and only one, reason to change.

  • Getting Software to work and making software clean are two very different activities.

    • Too many of us think we are done once the program works.

    • We fail to switch to the other concern or organization & cleanliness - breaking down overstuffed classes into decoupled units that follow the SRP.

  • Do a large number of small, single purpose classes make it more difficult to understand the bigger picture?

  • Would we rather have tools organized into toolboxes with many small drawers each containing well-defined and well-labeled components? Or do we want several large junk drawers?

  • The primary goal in managing complexity is to organize it so that a developer knows where to look to find things.

Summary

  • We want our systems to be composed of many small classes.

  • Each small class encapsulates a single responsibility, has a single reason to change, and collaborates with a few others to achieve the desired system behaviors.

Cohesion

  • Classes should have a small number of instance variables.

  • Each of the methods should manipulate one or more of those variables.

    • A class in which each variable is used be each method is maximally cohesive, but it's not advisable nor possible to achieve this fully.

  • When cohesion is high, methods and variables of the class are co-dependent.

Maintaining Cohesion Results in Many Small Classes

  • When classes lose cohesion, split them!

  • Breaking large functions into many smaller functions often gives us the opportunity to the code into several smaller classes.

Organizing for Change

  • We want to structure our systems so that we muck with as little as possible when we update them with new or modified features.

    • Small cohesive classes help us do this.

  • In an ideal system, we incorporate new features by extending the system, not by making modifications to existing code.

Open Closed Principle: Classes should be open for extension but closed for modification.

Isolating from Change

  • A client class depending on concrete details is at risk when details change.

    • Interfaces & abstract classes help isolate the impact of those details.

  • Dependencies on concrete details create challenges for testing our system.

    • A system that is decoupled enough to be tested will also be more flexible and promote more reuse.

  • A lack of coupling means that elements of our system are better isolated from each other and from change.

    • Isolation makes it easier to understand each element of the system.

  • Minimizing coupling helps us adhere to the Dependency Inversion Principle (DIP).

Dependency Inversion Principle: Classes should depend upon abstractions, not on concrete details.

Previous9: Unit testsNext12: Emergence

Last updated 24 days ago