Home » Java » Core Java » Fat vs. Skinny Design

About Yegor Bugayenko

Yegor Bugayenko
Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.

Fat vs. Skinny Design

It seems that type/class hierarchies in OOP may be designed in two extreme ways: either with full encapsulation of data in mind; or with just a few interfaces making raw data visible, and letting classes deal with it, parse it, and turn it into smaller data elements. You may be surprised, but I’m suggesting the second option is more elegant. It seems to me that we don’t lose object orientation, but rather gain a lot of flexibility, reusability, testability, and so on.

Owning Mahowny (2003) by Richard Kwietniowski

Take a look at this (let’s call it fat and I will explain why later):

01
02
03
04
05
06
07
08
09
10
11
interface Article {
  Head head();
}
interface Head {
  Author author();
  String title();
}
interface Author {
  String name();
  String email();
}

To obtain the name of the author we do:

1
2
3
4
// It is stored in PostgreSQL (that's why the Pg
// prefix) and retrieves everything using SQL
Article a = new PgArticle();
String name = a.head().author().name();

Visually, this design may look like this (in UML):

Can’t render PlantUML diagram.

Now, let’s compare it with an alternative design (which is much less fat than the previous one, I would even call it skinny):

01
02
03
04
05
06
07
08
09
10
11
12
13
interface Article {
  String head();
}
class TxtHead {
  private final Article article;
  String author();
  String title();
}
class TxtAuthor {
  private final Head head;
  String name();
  String email();
}

Here, in order to obtain the name of the author we have to extract the head as a String, extract the author as a String, and then extract the name as a String:

1
2
3
4
Article a = new PgArticle();
String head = a.head();
String author = new TxtHead(head).author();
String name = new TxtAuthor(author).name();

Visually in UML, it looks like this:

Can’t render PlantUML diagram.

There were three interfaces in the first design, while the second one has only one interface and two classes. I call the first one “fat” because it returns interfaces, which already implement the functionality we are looking for, and we don’t need to cover them with additional decorators or adapters. Its hierarchy of three interfaces is rich enough to give us everything we need. That’s why it’s fat. The second one, on other hand is pretty skinny, there is only one interface, which returns us plain text data, which we have to parse on our own. We need to dress it up.

It seems that the skinny design is better, for a number of reasons:

  • Extendability. The skinny design is definitely easier to extend. In order to extract some new information from the author we just need to add a new method to the class TxtAuthor. We don’t need to re-design the entire hierarchy of interfaces and to modify all their implementations. We deal with pure data, which is managed and parsed later, in decorators, adapters, and other supplementary smart classes.
  • Cohesion. The skinny design is definitely more cohesive, since everything that is related to the management of PostgreSQL data stays in one class SqlArticle. To the contrary, the fat design spreads the functionality among many classes and, thanks to that, makes the entire class-set more difficult to maintain.
  • Reusability. Class TxtAuthor can definitely be used in any other place, where parsing of an author’s information is required, while class PgAuthor is only suitable for one particular case: fetching and parsing PostgreSQL-related data.
  • Testability. Obviously, the skinny design is much easier to test, because mocking a single interface is a much simpler task than mocking the entire hierarchy. To test the class TxtAuthor we just pass some fake text to its constructor and check how it works. To test the class PgAuthor we would need to do much more, including running a fake instance of a PostgreSQL server.

Everything said above is true for both 1) from-PostgreSQL data retrievals and 2) to-PostgreSQL data manipulations. Of course, manipulations may require many methods to exist in SqlArticle, which will make the skinny design look ugly, and it will become obvious that some of these methods have to be moved to lower-level classes/interfaces. This only demonstrates that it’s not always possible to make skinny design with a single interface, like in the example above. Sometimes we simply have to make it more fat.

However, there is one serious concern related to the skinny design: it lets the raw naked data jump out of SqlArticle, which is against the very idea of object-oriented programming, as we know. Indeed, if we let TxtHead do the parsing, we may lose some interesting PostgreSQL-related context, which is available only inside SqlArticle. We don’t want complex data parsing to happen far away from the place where the data is born. We want everything data-related to happen where the data lives: inside SqlArticle.

This is a valid concern, but letting PostgreSQL-related information (like connection settings) move from PgArticle to PgHead and then to PgAuthor is an even larger violation of the data encapsulation principle.

In real-life situations, of course, it’s not possible to imagine pure one-interface skinny designs. They will all be fat to some extent. My suggestion, though, is to try to make designs less fat, letting interface users dress them up however they like. This suggestion is very close to what I said earlier about smart classes, but this time the principle is broader.

Published on Java Code Geeks with permission by Yegor Bugayenko, partner at our JCG program. See the original article here: Fat vs. Skinny Design

Opinions expressed by Java Code Geeks contributors are their own.

(0 rating, 0 votes)
You need to be a registered member to rate this.
2 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Pete
Pete
1 year ago

“Visually, this design may look like this (in UML):

Can’t render PlantUML diagram.”

Serhiy Palamarchuk
Serhiy Palamarchuk
1 year ago

It looks like a demo of IS-A and HAS-A but for different use cases and different context. It is up to the domain and context which should drive the design. Domain is evolving and may change over time. What if content of article has changed that parser cannot read it adequately?