14

According to Jeff Bay's Essay on Object Callisthenics,

One of the practices is set to be "Wrap all primitives and Strings"

Can anyone elaborate on this ?

In languages where we already have wrappers for primitives like C# and Java. and In languages where Collections can have generics where you are sure of what type goes into the collection, do we need to wrap string's inside their own classes ?

Does it have any other advantage ?

Tulains Córdova
  • 39,570
  • 13
  • 100
  • 156

4 Answers4

19

Imagine a situation where you have a primative type:

int distanceInKm;

This is in many, many places throughout your code.

One day Mr Client comes to you and says, "We'd like everything displayed in miles now, please."

You now have to change everywhere where distanceInKm is used.

Now imagine an alternative situation where you have you own type:

class Distance
{
    private int _distanceInKm;

    public string DescriptionOfDistance()
    {
        return ...;
    }
}

Now you only need to change one place to make everything display in miles.

As @DanielFisherlennybacon has mentioned in the comments, you need to be pragmatic about when to apply any 'rules' of programming. In this specific case, it is worth noting that Object Calisthenics is an exercise to stretch your programming muscles. Marathon runners do sprints in training to improve their basic speed; it doesn't mean they have to sprint for the entire race.

Scroog1
  • 1,115
  • 8
  • 9
16

In fact, the article repeatedly states that it is not best practice to blindly wrap all primitives:

The Challenge Do a simple project using far stricter coding standards than you’ve ever used in your life. Below, you’ll find 12 “rules of thumb” that will help push your code into good object-oriented shape.

By suspending disbelief, and rigidly applying these rules on a small, 1000 line project, you’ll start to see a significantly different approach to designing software. Once you’ve written 1000 lines of code, the exercise is done, and you can relax and go back to using these 12 rules as guidelines.

This is a hard exercise, especially because many of these rules are not universally applicable. The fact is, sometimes classes are a little more than 50 lines. But there’s great value in thinking about what would have to happen to move those responsibilities into real, first-class-objects of their own. It’s developing this type of thinking that’s the real value of the exercise. So stretch the limits of what you imagine is possible, and see whether you start thinking about your code in a new way.

Why would you post a question asking to explain an article you haven't read?

Here is what it says:

Rule 3: Wrap all primitives and Strings In the Java language, int is a primitive, not a real object, so it obeys different rules than objects. It is used with a syntax that isn’t object-oriented. More importantly, an int on its own is just a scalar, so it has no meaning. When a method takes an int as a parameter, the method name needs to do all of the work of expressing the intent. If the same method takes an Hour as a parameter, it’s much easier to see what’s going on. Small objects like this can make programs more maintainable, since it isn’t possible to pass a Year to a method that takes an Hour parameter. With a primitive variable the compiler can’t help you write semantically correct programs. With an object, even a small one, you are giving both the compiler and the programmer additional info about what the value is and why it is being used.

Small objects like Hour or Money also give us an obvious place to put behavior that would otherwise have been littered around other classes. This becomes especially true when you apply the Rule X, and only the small object can access the value.

9

Scroog1's answer covers adding context to a value. Another example: say you have

public void SubmitOrder(int productId, int customerId) { ... }

then there is always the possibility that you call it as so:

processor.SubmitOrder(customerId, productId);

Ouch. Let's hope you wrote a unit test that checked which value was passed in which place. But if you define:

public void SubmitOrder(ProductID pid, CustomerID cid) { ... }

then the compiler will stop you getting it wrong. For a small project this may well be overkill; for a large one where bugs have life-or-death consequences it may well stop you having sleepless nights.

-1

Trivially no. Absolutely not. It's a bad idea for the same reason that if(boolValue==true) is a bad idea. If it was a good idea, doing it twice would be even better: if((boolValue==true)==true) or WrappedWrappedString. But a boolean is already a boolean, and a string is already an abstraction that wraps a container of characters.

A successful design pattern modifies a primitive component to perform a related but different task. A design pattern which modifies a primitive component to perform the same task adds no value and causes entirely avoidable confusion.

MSalters
  • 9,038