Value Objects: AppCode’s Code Generation to the Rescue

Click to play

January 12, 2016

6  comments

A Value Object is a handy way to combine multiple values in a single object. It sounds simple—you just make each value a property, right? Well, there’s usually more to it than that. There’s even an entire objc.io article about Value Objects. …So how do you define a new Value Object?

I believe in laziness. Let’s do as little work as possible!

[This post is part of the series TDD Sample App: The Complete Collection …So Far]

What We Need

In the Marvel Browser iOS TDD sample app, the goal is to display comic characters whose names start with a given prefix. The Marvel Comics API offers many parameters for fetching characters. We want to use just three of them:

  • nameStartsWith
  • limit
  • offset

This will allow us to fetch the results a page at a time, and request the next page.

Services Are Better Without State

The page size will likely be a fixed quantity in the app. We could build a Service that knows this fixed quantity. It could also keep track of the offset, encapsulating “request the next page.”

Disclosure: The book links below are affiliate links. If you buy anything, I earn a commission, at no extra cost to you.

I’ve written Services like that before. But the guidance given by Domain-Driven Design is “make the Service stateless.” Why?


What we get is a Service that is ignorant about our app.

This makes testing easier. It also opens the door to reusability. As I wrote last time: when it comes to objects, ignorance is bliss!

A Service that is ignorant about our app makes testing easier and opens the door to reusability.

Click to Tweet

Generating Value Objects with AppCode

So we’ll pass in three parameters. Let’s pass them together as a Value Object. Are you ready?

Instead of assembling another set of screenshots, I made a screencast—my shortest yet. It’s just three-and-a-half minutes long.

Whether you use Xcode or AppCode, be sure to get my free set of test snippets:

Sign Up to Receive Swift and Objective-C Test Code Snippets

Get our newsletter on Quality Coding techniques for iOS developers & get instant free access to the free code snippets:

We take your privacy seriously.  See our privacy policy here.

Let’s picture what it means to make the Service stateless. In our example, it means the Service won’t track the prefix, the page size, or the page offset. We’ll track these values elsewhere in the app. The Service only does what it’s told. 

Links:

What do you think about stateless Service objects? Have I convinced any of you to try AppCode yet? Leave a comment below.

[This post is part of the series TDD Sample App: The Complete Collection …So Far]

How to Use Dependency Injection to Make Your Code Testable

Jon Reid

About the author

Programming was fun when I was a kid. But working in Silicon Valley, I saw poor code lead to fear, with real human costs. Looking for ways to make my life better, I learned about Extreme Programming, including unit testing, test-driven development (TDD), and refactoring. Programming became fun again! I've now been doing TDD in Apple environments for 20 years. I'm committed to software crafting as a discipline, hoping we can all reach greater effectiveness and joy. Now a coach with Industrial Logic!

    • Juan, there’s really no need for such a test. Here’s why: Other tests will use the Value Object by creating and initializing it with certain values. Those tests will then confirm that the input (via the initializer) affects the output in a certain way.

      Did that make sense?

      • Yes, it makes sense. But at this stage of the project there is production code that is not tested (the body of the initializer). If you comment out that code and return nil, unit tests still pass. So we broke the rule “You are not allowed to write any production code unless it is to make a failing unit test pass.”

        This is why I thought the unit test is needed now. Maybe it can be removed later if it adds no value.

        Maybe I’m too strict applying TDD.

        Thanks for your response!

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

    Never miss a good story!

    Want to make sure you get notified when I release my next article or video? Then sign up here to subscribe to my newsletter. Plus, you’ll get access to the test-oriented code snippets I use every day!

    >