`

Never, never, never use String in Java (or at least less often :-)

    博客分类:
  • Tips
阅读更多

Never, never, never use (unwrapped) String or long or int. Why? Those primitive types have no semantic meaning. They are hard to understand, hard to maintain, and hard to extend. I’ve been evangelizing this concept for some time, the essay “Object calisthenics” finally prompted be to write this post. Suppose we have an example of a cinema ticket booking service.

Update: If you just want to drop a comment telling me how revolting you find the idea, well, just don’t. I appreciate your comment, but sit back, think some time about it and move on coding. When you read someone else code with String id and you wonder what on earth the id is, come back and read this post.

Compare

public void bookTicket(
  String name,
  String firstName,
  String film,
  int count,
  String cinema);

with (and I know one would introduce an Order object for real code):

public void bookTicket(
  Name name,
  FirstName firstName,
  Film film,
  Count count,
  Cinema cinema);

The second one is much easier to understand, especially when your IDE is one that tells you during autocompletion of a method call bookTicket(String arg0, String arg1, String arg2, int arg3, String arg4) versus bookTicket(Name arg0, FirstName arg1, Film arg2, Count arg3, Cinema arg4). The second one is also much easier to read.

Compare

void book(String orderId);

with

void book(OrderId order);

In the first case the developer seeing the code wonders a.) where to get an orderId and b.) what an orderId really is, "1212", "ABC-123" or "12-34-45-SCHWEINEBACKE". In the second case he can search for the usage of the OrderId class, how it is used, read the javadoc and only pass validated and correct order ids into an application. You might think an orderId is just an orderId, easy to find. Legacy systems will change the id, the naming and semantics in often inconsistent ways. I’ve seen systems that name an order ID in serveral ways as “orderId”, “AuftragsId”, “id” and several other names and all meaning the same thing!

It’s easier to have a class with semantics than a domain-less String. Developers cannot as easily mess up. If you rely on static typing and use a startic type language (both object and reference) then maximize your benefits and create more classes. In the future an OrderId class can also easily be changed to hold long instead of an int, hold validation or id generation logic. It’s much harder to extend the initial String based version.

Implementation with a fluent interface

The classes should be implemented as simple Domain classes, sometimes as immutable value objects, which just wrap String and attach some semantic meaning to the String.

public class Name {
   public Name(String name) {
      ...
   }
   public static Name name(String name) {
     return new Name(name);
   }
}

One would wonder if the solution is too noisy. Assuming

new Customer(new FirstName("Stephan"), new Name("Schmidt"));

is certainly noiser than a String argument:

new Customer("Stephan", "Schmidt");

The first is easier to understand though, and with static methods can be changed to

new Customer(firstName("Stephan"), name("Schmidt"));

This also solves the problems that with many arguments developers from reading the code don’t understand what each parameter means, especially in longer (refactor to parameter object!) parameter lists. This is another approach to Fluent Interface builders.

My last post on how to use generics with immutable objects could also be extended with value objects instead of primitives.

new Point(10,10);
new Point(x(10), y(10));

where x(10) and y(10) create Xpos and Ypos value objects.

Domain objects vs. primitivs in interview questions

One of the interview questions I like is to ask people about an interface for a price search. I usually give them

... searchByPrice(...)

and let candidates fill in the missing parts. Some will write

Vector searchByPrice(double start, double end)

which is bad code from several points of view (using double for money, no domain objects, untyped Vector).

Others with more domain based thinking write

List<Product> searchByPriceRange(Price start, Price end)

or even us the Range pattern by Fowler:

List<Product> searchByPriceRange(PriceRange priceToSearch)

The last solution is easy to extend and understand. Answering this question often starts an interesting discussion on interface design, maintainablity and domain modelling. Whatever you think about this interview question, don’t forget to once and for all: Do not use double for money.

Thanks for listening and don’t use String, int and long (or double for money).

Update:

If you find the usage of Classes instead of Strings repulsive, look at another example, zip code. Most people I’ve seen in lots of code use a primitive for zip code which creates a lot of problems when going i18n.

Customer {
   String name;
   String street;
   String city;
   String zip;
}

(some will have used int for the zip code but get faster into trouble than the String users)

instead of

Customer {
   String name;
   Address address;
} 

Address {
   ZipCode code;
}

Still think Strings are a good idea in your code or “the simplest thing that could possibly work”?

 

o-Link : http://codemonkeyism.com/never-never-never-use-string-in-java-or-at-least-less-often/

分享到:
评论

相关推荐

    Analytics-Journal-Never-2021-10-15-080348.ips.ca.synced

    Analytics-Journal-Never-2021-10-15-080348.ips.ca.synced

    ApophisAndroid:Never-Die-Zombieroid :comet::woman_vampire:

    ApophisAndroid: Never-Die-Zombieroid :shooting_star: :female_sign:‍:female_sign: SOPT 27日17日APP-JAM:Apophis :shooting_star: :pushpin: 部分会议 每天晚上7:30 :artist_palette: 看板 :wrench: 工具...

    spring-javaconfig-reference

    This document assumes at least a general familiarity with the Spring IoC container. If you are brand new to Spring (i.e.: have never used Spring's XML configuration language, it is suggested that you ...

    Modern Java In Action 2019

    Put simply, the new features in Java 8 along with the (less-obvious) changes in Java 9 are the biggest change to Java in the 21 years since Java 1.0 was released. Nothing has been taken away, so all ...

    MMC-1常见问题解析

    MMC-1常见问题解析MMC-1常见问题解析MMC-1常见问题解析

    All In One(AIO) V1.0

    例子: Aio.exe -Never Guest 帮助: Aio.exe -Never 17.PowerOff -&gt; 关机,关电源 用法: Aio.exe -PowerOff 18.Pslist -&gt; 列进程 用法: Aio.exe -Pslist 19.Pskill -&gt; 杀进程 用法: Aio.exe -Pskill PID|进程名 ...

    Pragmatic Unit Testing in Java 8 with JUnit(PACKT,2015)

    Pragmatic Unit Testing in Java 8 With JUnit steps you through all the important unit testing topics. If you've never written a unit test, you'll see screen shots from Eclipse, IntelliJ IDEA, and ...

    C++出错提示英汉对照表

    Parameter ''xxx'' is never used ------------------能数xxx没有用到 Pointer required on left side of -&gt; -----------------------符号-&gt;的左边必须是指针 Possible use of ''xxx'' before definition --------...

    High Performance in-memory computing with Apache Ignite.pdf

    You are planning to process continuous never-ending streams and complex events of data in a scalable and fault-tolerant fashion. You want to use distributed computations in parallel fashion to gain ...

    C# 5.0 All-in-One For Dummies

    For the newcomer — if you’ve never programmed in C#, learn all the essentials in the first two minibooks Delve into design — discover the key elements of databases, files, and graphics and how to ...

    After Hours: 10 Projects You'll Never Do at Work

    Java After Hours: 10 Projects You'll Never Do at Work will make Java your playground with ten detailed projects that will have you exploring the various fields that Java offers to build exciting new ...

    system mechanic Activator v1.0

    (if it's not in Quarantaine then look at History or something similar). 04- To avoid risks when using cracks also Sandboxie can be used to test them: http://www.sandboxie.com/ ...

    ffmpeg最新版 windows版本 可以执行文件

    usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... Getting help: -h -- print basic options -h long -- print more options -h full -- print all options (including...

    java源码war-udemy-java-warrior:Udemy课程“放码过来!作个Java实战派”源代码

    java 源码 war “放码过来!作个Java实战派”课程源代码 版本一览 JDK 12.0.1,启用preview阶段功能 MAVEN 3.6.1 Intellij IDEA Ultimate 2019.1 参考资源 :star: Java Never Sleep :star: Java Never Sleep :star: ...

    never-give-up:永不放弃的PyTorch实现

    永不放弃 永不放弃的PyTorch实施:学习定向探索策略[] 仅实施了具有嵌入网络的偶然性好奇心。 安装 使用Python 3.7.9测试 pip install -r requirements.txt 火车 python train.py 结果 ...R2D2基地是从通过

    FlexGraphics_V_1.79_D4-XE10.2_Downloadly.ir

    Returns True if the string must be enclosed in quotes (flex-property value) before saving in the filer. - ADD: In the class TFlexGrid added the methods DoSnap and DoCustomSnap (the last one can be ...

    Unit1NeverGiveIn,Never,Never,Never习题集答案解析综合教程四.doc

    Unit1NeverGiveIn,Never,Never,Never习题集答案解析综合教程四.doc

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Another useful rule of thumb: it's typically not cost effective to inline functions with loops or switch statements (unless, in the common case, the loop or switch statement is never executed)....

    smali2java.jar

    You can use dex2jar or smali2java or both. Technical questions Does smali2java check smali syntax? All of syntax checks are based on parser workflow. At this time smali2java provides this ...

    Never-Ending-Story-Android:Never Ending Story 安卓端游戏 [测试版本]

    Never-Ending-Story-Android概述这个项目是 Never Ending Story 游戏项目的测试版本,现在暂无法真正实现其功能。。目标这个项目是我的一个小目标,大概是10到13个月的小项目。因为最近发生了很多事,所以这个项目...

Global site tag (gtag.js) - Google Analytics