This is a mobile version, full one is here.

Yegor Bugayenko
12 September 2017

Yet Another Evil Suffix For Object Names: Client

Some time ago we were talking about "-ER" suffixes in object and class names. We agreed that they were evil and must be avoided if we want our code to be truly object-oriented and our objects to be objects instead of collections of procedures. Now I'm ready to introduce a new evil suffix: Client.

Let me give an example first. This is what an object with such a suffix may look like (it's a pseudo-code version of the AmazonS3Client from AWS Java SDK):

class AmazonS3Client {
  createBucket(String name);
  deleteBucket(String name);
  doesBucketExist(String name);
  getBucketAcl(String name)
  getBucketPolicy(String name);
  listBuckets();
  // 160+ more methods here
}

All "clients" look similar: they encapsulate the destination URL with some access credentials and expose a number of methods, which transport the data to/from the "server." Even though this design looks like a proper object, it doesn't really follow the true spirit of object-orientation. That's why it's not as maintainable as it should be, for two reasons:

The consequences depend on the situation, but these are the most probable:

What is the alternative?

The right design would be to replace "clients" with client-side objects that represent entities of the server side, not the entire server. For example, with the S3 SDK, that could be Bucket, Object, Version, Policy, etc. Each of them exposes the functionality of real buckets, objects and versions, which the AWS S3 can expose.

Of course, we will need a high-level object that somehow represents the entire API/server, but it should be small. For example, in the S3 SDK example it could be called Region, which means the entire AWS region with buckets. Then we could retrieve a bucket from it and won't need a region anymore. Then, to list objects in the bucket we ask the bucket to do it for us. No need to communicate with the entire "server object" every time, even though technically such a communication happens, of course.

To summarize, the trouble is not exactly in the name suffix, but in the very idea of representing the entire server on the client side rather than its entities. Such an abstraction is 1) too big and 2) very data driven.

BTW, check out some of the JCabi libraries (Java) for examples of object-oriented clients without "client" objects: jcabi-github, jcabi-dynamo, jcabi-s3, or jcabi-simpledb.