DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. JavaScript
  4. The 4 rules of simple design

The 4 rules of simple design

Giorgio Sironi user avatar by
Giorgio Sironi
·
May. 17, 11 · Interview
Like (0)
Save
Tweet
Share
41.43K Views

Join the DZone community and get the full member experience.

Join For Free

A colleague of mine told me a bit ago that Red-green instead of Red-green-refactor was becoming an issue: many commits where made just when the green bar was reached. A reason for this behavior was the fear of overdesigning the system and code for tomorrow instead of today: XP stresses the concept of just solving today's problem instead of anticipating future issues incorrectly and design for the wrong change.

At the same time, code which design is not improved after the green bar is prone to not be clean and sustainable, unless you are very keen in the process of design *during* the red phase (with a clean definition of Mocks and Stubs).

These four famous rules are what will force you to write clean code during TDD instead of stopping at a green bar.

The list

You're done with the refactor 3rd phase when the code (which by the way, is the design):

  1. Passes all the tests.
  2. Express every idea we need to express.
  3. Contains no duplication.
  4. Minimized the number of classes, methods and other moving parts.

Let's dumb it down what we are developing (a single class for example) and anayze the rules and how they apply to our typical process.

I think there is an order of importance here, where the tradeoff for improving i over i +1 is to be preferred. The order of points 2 and 3 vary according to the sources, but if I had to choose between them I would prefer expressiveness over absence of duplication.

1. Passes all the tests is the most important rule. If you go back to a red bar, your refactoring is not valid and you should return to a green state to start again. Refactoring in red is dangerous and theoretically (we're all human) you shouldn't stay red for more than a few minutes.

This rule also means that if you write code not for satisfying a test (unit or end-to-end or functional or any other kind, it does not matter), you're not even satisfying the first of 4 requisites.

This should be your best friend:

2. Express every idea we need to express. Given that your code passes all the tests, you can explicit concepts to "show" your design. For example concrete classes or delegation of methods that do not change the implementation are acceptable for communication, even if technically they constitute a duplication and violate 3 (which is less important in this case imho).

For example, these two classes:

class AsideBox extends DivTag {}
class ArticleText extends DivTag {}

are important for me on the semantic level, even if they do not modify any detail of DivTag. They can also be used for type hints in dynamic languages or finer compile-time checks in statically typed ones.

3. Given that the code passes the tests and expresses your design reliably, you can extract methods and classes all the way down to eliminate duplication. This rule is widely diffused and talked about, I think for its simplicity of application; it's simple to see duplication in the majority of cases: what is not so simple is instead expressing all concepts that came up during development (2).

There is a trade-off between extraction of duplicated code and its clarity. I remember extracting an abstract class similar to this a while ago:

abstract class ChangeOperation {
    protected ChangeRegistry registry;
    public function ChangeOperation(ChangeRegistry registry) {
        this.registry = registry;
    }
}

to eliminate the duplicated constructor. This operation is on the boundary of my list of refactorings: extracting any more code just breaks down objects into abstract concepts instead of a readable object model. If I weren't able to quickly meaningfully name this abstract class, I would just avoided extracting it.

4. Simple design is taking out whatever you can from your code without violating 1, 2, and 3. The bar should remain green, you should not suffer from deleting useful concepts that make the code more readable and understandable, and you shouldn't introduce duplication in the process (for example inlining again a class or method).

This rule fosters evolutionary design instead of design for tomorrow. You can choose to write code foreseeing change, and introduce complexity to handle future changes (Strtegy/Bridge). But since it's impossible to predict axis of change consistently, you end up introducing complexity for daeling with change that doesn't happen, while refactoring is needed anyway for unpredicted changes.

More references

Design is an ability that is picked up in years: but I hope to have shed a little light over these principles, which read by themselves may seem just an ideal composed of buzzwords. As always, these are the giants whose shoulder we stand on.

C2 wiki on XP Simplicity Rules

Uncle Bob's Clean Code

Extreme Programming Explained, 2nd edition by Kent Beck

Design Express Concept (generic programming) Testing Pass (software) Trade-off Extreme programming IT

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Application Architecture Design Principles
  • Fargate vs. Lambda: The Battle of the Future
  • Stop Using Spring Profiles Per Environment
  • Introduction to Container Orchestration

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: