Tencent almost a decade Gangster: I did not hit you! You may not really write Java

Java confidant

The core article

In fact, this title did not want to write so horrible, but found that many people did a few years after Java, all think it is a good Java programmer, and can hold thousands of wages at promoting their own, and write this the purpose of the article was not mocking me to do the same Java colleagues, readers just want to see after this article, you can like me, calmly trying to do a good programmer.

Tencent almost a decade Gangster: I did not hit you! You may not really write Java

No public concern: " Java confidant " send " 1024 " to receive a free 30 classic programming books . Progress with 100,000 programmers. Java knowledge is updated daily Oh, look forward to your arrival!

About the direction

As has been engaged in mobile Internet-related work, Java developers frequently and mobile end deal or do some back-end work, so this article is more likely to involve interaction and interactive mobile end or back-end, I want to own some of the learning experience or development experience, you can drive carefully read this article readers, so that we can have a better attitude Java to learn it, it's not just a money-making tool.

The author around a lot and I age or older friends or colleagues, I am often asked: "? You still learning right now I do not think there studious, these things are about the same," I always answer given time, I'm going to look for a book, this time, it will reveal a disdain in the eyes or smile. In fact, very able to understand the views of close friends or colleagues, the current state is concerned, most of them are programmers work at least five years, and for companies large and small business needs, the current stock of knowledge is concerned, you can easily response, "nothing studious" in fact, this sentence is not much of a problem, but if you are programming a little bit interested, just do not know how hard or improve, I hope this article can help you.

Technical points

This is not a boast article, do not speak a lot of advanced architecture, on the contrary, will explain many basic questions and written questions, if readers think the basis of the wording of questions and problems are not a problem, then please ignore this article, save a time to do something worthwhile.

development tools

I do not know how many "old" programmers are still using Eclipse, these programmers either the beaten track, or else simply do not know there are other good development tools, Eclipse eat memory card Dayton phenomenon and various occasional inexplicable abnormal appearance, we are told that it is time to find a new development tool.

Replace the IDE

Simply do not want to explain what kind of IDE want to change, if you want to be a good Java programmer, replace IntelliJ IDEA. The benefits of using IDEA, search Google.

Do not tell me the shortcut does not work well

Replace the IDE is not my main focus of this article, so do not want to use too much space to write Why replace the IDE. Here, I can only tell you replace the IDE in order to better and faster just to write Java code. A Cause.

Do not tell me the shortcut does not work well, try new things.

bean

bean allows us to use one of the largest model, I will go to great length to explain the bean, I hope the reader a good experience.

domain name package

According to many Java programmers 'experience' point of view, a database table corresponds with a domain object, so many programmers write code at the time, the package name is used: com.xxx.domain, write seems to have become the industry's a constraint, database mapping objects should be the domain. But you are wrong, domain is a domain object, often we do the traditional Java Web development software, these are anemic domain model, there is no act or behavior does not have enough domain model, so to this theory speaking, these domain should be a common entity objects, not domain objects, so please read the package name: com.xxx.entity.

If you do not understand what I say, take a look at Vaughn Vernon out of a book called "IMPLEMENTING DOMAIN-DRIVEN DESIGN" (domain-driven design to achieve) the book, the book explains the difference between anemic model and domain model, I believe you It will benefit.

DTO

Data transmission should we use DTO objects as transport objects, this is what we agreed, because for a long time I've been working on mobile-side API design work, a lot of people told me that they think only to the transfer of data when the phone (input or output), these objects become DTO objects. Please note! This understanding is wrong, as long as the object is used for network transmission, we believe they can be used as a DTO object, such as electronic business platform, a single user, the data after the order, the order will be sent to OMS or ERP system, the return values ​​and the docking is also called the reference DTO objects.

We agreed that if an object DTO objects, changed the name to XXDTO, such as OMS issued an order: OMSOrderInputDTO.

DTO transformation

As we know, DTO model object systems to interact with the outside world, then there will certainly be a step into the DTO objects BO object or objects is a common entity, so that service layer to deal with.

Scenes

For example, to add profile operation, due for presentation, I consider only some simple user data when users click Add background administrator only needs to pass over the user's name and age on it, after the back-end data is received, add created and updated three times and the default password field, and then save the database.

@RequestMapping("/v1/api/user")
@RestController
public class UserApi {
    @Autowired
    private UserService userService;
    @PostMapping
    public User addUser(UserInputDTO userInputDTO){
        User user = new User();
        user.setUsername(userInputDTO.getUsername());
        user.setAge(userInputDTO.getAge());
        return userService.addUser(user);
    }
} 

We only look at the conversion code in the code above, other content, please ignore:

User user = new User(); 
user.setUsername(userInputDTO.getUsername()); 
user.setAge(userInputDTO.getAge()); 

Please use the tool

Code above, logically, there is no problem, but such an approach makes me so tired, case only two fields, if there are 20 fields, how do we do it? One of a set of data? Of course If you do, certainly not a problem, but this is certainly not an optimal approach.

There are many online tools, support Utils shallow copy or a deep copy. For example, we can use org.springframework.beans.BeanUtils # copyProperties the code refactoring and optimization:

@PostMapping
public User addUser(UserInputDTO userInputDTO){
    User user = new User();
    BeanUtils.copyProperties(userInputDTO,user);
    return userService.addUser(user);
}

BeanUtils.copyProperties method is a shallow copy, copy attributes, we only need DTO objects and attribute values ​​of the two objects to be transformed to the same name, and to ensure that the same type of it. If you have been using a set of properties assigned to do the conversion when DTO, try to simplify the code this way, to make the code more clear!

Transformation semantics

Top of the conversion process, the reader must have felt after watching a lot of elegance, but we write Java code, need to consider more operational semantics, look at the top of the code:

User user = new User(); 
BeanUtils.copyProperties(userInputDTO,user); 

Although this code good simplify and optimize the code, but he is a semantic problem, we need to cash a transformation process we go, so the code changed as follows:

@PostMapping
public User addUser(UserInputDTO userInputDTO){
    User user = convertFor(userInputDTO);
    return userService.addUser(user);
}
private User convertFor(UserInputDTO userInputDTO){
    User user = new User();
    BeanUtils.copyProperties(userInputDTO,user);
    return user;
}

This is a better semantic writing, although he trouble some, but greatly increases the readability when writing code, we should try to put a semantic level similar methods, such as:

User user = convertFor(userInputDTO); 
return userService.addUser(user); 

This two pieces of code are not exposed to achieve, are talking about how the same approach, the same level to do a set of semantic operations, rather than specific implementations exposure.

As described above, a reconstruction mode, the reader can refer to Martin Fowler's "Refactoring Imporving the Design of Existing Code" (reconstruction to improve the design of existing code) Extract Method reconstructed embodiment of this book.

Abstract interface definition

When the actual work to complete the transformation several DTO API, we will find that there are many, many such operations, it should be a good definition of the interface, so that all such operations have rules of conduct.

If after the interface is defined, then the semantic convertFor this method will produce a change, it is an implementation class.

After a look at the interface of the abstract:

public interface DTOConvert<S,T> { 
 T convert(S s); 
} 

Although the interface is very simple, but here to tell us a thing, gonna use generics, if you are a good Java programmer, you want to ask for the abstract interface, make it generic.

We look interface:

public class UserInputDTOConvert implements DTOConvert {
    @Override
    public User convert(UserInputDTO userInputDTO) {
        User user = new User();
        BeanUtils.copyProperties(userInputDTO,user);
        return user;
    }
}

After the reconstruction of us, now we find code that is so simple, and so specification:

@RequestMapping("/v1/api/user")
@RestController
public class UserApi {
    @Autowired
    private UserService userService;
    @PostMapping
    public User addUser(UserInputDTO userInputDTO){
        User user = new UserInputDTOConvert().convert(userInputDTO);
        return userService.addUser(user);
    }
}

review code

If you are a good Java programmer, I believe you should like me, I have had several repeated review their own code many times.

We look at this to save the user's example, you will find, API return value is some problem, the problem is directly returned User entity should not, because if so, it exposes too much information related entity, such return value is unsafe, so we should return a DTO object, we can call it UserOutputDTO:

@PostMapping
public UserOutputDTO addUser(UserInputDTO userInputDTO){
    User user = new UserInputDTOConvert().convert(userInputDTO);
    User saveUserResult = userService.addUser(user);
    UserOutputDTO result = new UserOutDTOConvert().convertToUser(saveUserResult);
    return result;
}

So that your API is more robust.

Do not know after reading this code, readers discover whether there exist other problems, as a good Java programmer, take a look at this code we have just finished the abstract:

User user = new UserInputDTOConvert().convert(userInputDTO); 

You will find, new DTO such a conversion target is not necessary, and each transformed objects are made to appear in the face of DTO transformation, then we should consider whether this class and can be polymerized it DTO look at my aggregation results:

public class UserInputDTO {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public User convertToUser(){
        UserInputDTOConvert userInputDTOConvert = new UserInputDTOConvert();
        User convert = userInputDTOConvert.convert(this);
        return convert;
    }
    private static class UserInputDTOConvert implements DTOConvert<UserInputDTO,User> {
        @Override
        public User convert(UserInputDTO userInputDTO) {
            User user = new User();
            BeanUtils.copyProperties(userInputDTO,user);
            return user;
        }
    }
}

Then transformed by the API:

User user = new UserInputDTOConvert().convert(userInputDTO); 
User saveUserResult = userService.addUser(user); 

became:

User user = userInputDTO.convertToUser(); 
User saveUserResult = userService.addUser(user);

We then added a DTO object behavior transformation, I believe that such an operation can make code readability becomes stronger, and is in line with semantics.

Then check tools

Let's look at the code inside DTO transformation, which implements the interface DTOConvert our own definition, but this is really no problem, no need to think of it?

I think not, for the Convert this transformation semantics is concerned, there are a lot of tools in such a definition, which in Convert interface definition is not on the business level, it is just common sense for converting between common bean property values the interface definition, so we should be more to read other code containing convert transformation semantics.

I read a bit GUAVA source code, find the definition of this com.google.common.base.Convert:

public abstract class Converter<A, B> implements Function<A, B> { 
 protected abstract B doForward(A a); 
 protected abstract A doBackward(B b); 
 //其他略 
} 

Can be learned from the source, GUAVA the Convert to complete the conversion and reverse conversion forward, we continue to modify the code in the DTO transformation:

private static class UserInputDTOConvert 
        implements DTOConvert<UserInputDTO,User> {
    @Override
    public User convert(UserInputDTO userInputDTO) {
        User user = new User();
        BeanUtils.copyProperties(userInputDTO,user);
        return user;
    }
}

Modified:

private static class UserInputDTOConvert extends 
        Converter<UserInputDTO, User> {
    @Override
    protected User doForward(UserInputDTO userInputDTO) {
        User user = new User();
        BeanUtils.copyProperties(userInputDTO,user);
        return user;
    }
    @Override
    protected UserInputDTO doBackward(User user) {
        UserInputDTO userInputDTO = new UserInputDTO();
        BeanUtils.copyProperties(user,userInputDTO);
        return userInputDTO;
    }
}

After reading this code, you might ask, what use is it the reverse transformation? In fact, we have a lot of small business needs in a reference to the Senate and is the same, then we can easily become transformed, I the top mentioned UserInputDTO and UserOutputDTO are transformed into UserDTO show you.

DTO:

public class UserDTO {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public User convertToUser(){
        UserDTOConvert userDTOConvert = new UserDTOConvert();
        User convert = userDTOConvert.convert(this);
        return convert;
    }
    public UserDTO convertFor(User user){
        UserDTOConvert userDTOConvert = new UserDTOConvert();
        UserDTO convert = userDTOConvert.reverse().convert(user);
        return convert;
    }
    private static class UserDTOConvert extends
            Converter<UserDTO, User> {
        @Override
        protected User doForward(UserDTO userDTO) {
            User user = new User();
            BeanUtils.copyProperties(userDTO,user);
            return user;
        }
        @Override
        protected UserDTO doBackward(User user) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user,userDTO);
            return userDTO;
        }
    }
}

API:

@PostMapping
public UserDTO addUser(UserDTO userDTO){
    User user = userDTO.convertToUser();
    User saveResultUser = userService.addUser(user);
    UserDTO result = userDTO.convertFor(saveResultUser);
    return result;
}

Of course, this just shows the forward or reverse direction transformation, the participation and the participation of many objects DTO business needs are different, then you need to tell the program more obvious: the reverse is not invoked:

private static class UserDTOConvert extends 
        Converter<UserDTO, User> {
    @Override
    protected User doForward(UserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO,user);
        return user;
    }
    @Override
    protected UserDTO doBackward(User user) {
        throw new AssertionError("不支持逆向转化方法!");
    }
}

Look doBackward method, direct throw an assertion exception rather than business exception, this code tell the code of the caller, this method is not allowed you to call if you call, I will, "asserted that" you call wrong.

bean validation

If you think I write on top of the API to add a user to write has been very perfect, it only shows that you are not a good programmer. We should ensure that the reference to any method of in vivo data are legitimate.

Why verify

Many people will tell me if these are provided API call to the front end, the front end will be verified ah, why you have to validate?

In fact, the answer is this, I do not believe anyone call me or API methods, such as front-end validation fails, or some people through special channels (such as Charles were Ethereal), incoming data directly to my API, I still conduct normal business logic processing, it is possible to produce dirty!

"For generating dirty data must be fatal," I hope you keep in mind these words, then a small dirty data is also possible for you to find a few overnight!

jsr 303 verification

jsr hibernate provided 303 to achieve, I think it is still very good, specifically how to use, I do not want to say this because you can search on Google a lot of answers!

API examples will be described further above classes, we now examine the data DTO:

public class UserDTO { 
 @NotNull 
 private String username; 
 @NotNull 
 private int age; 
 //其他代码略 
} 

API authentication:

@PostMapping
public UserDTO addUser(@Valid UserDTO userDTO){
    User user = userDTO.convertToUser();
    User saveResultUser = userService.addUser(user);
    UserDTO result = userDTO.convertFor(saveResultUser);
    return result;
} 

We need to verify the results to the front end, which should be converted to a api abnormal abnormality (abnormality with an error code).

@PostMapping
public UserDTO addUser(@Valid UserDTO userDTO, BindingResult bindingResult){
    checkDTOParams(bindingResult);
    User user = userDTO.convertToUser();
    User saveResultUser = userService.addUser(user);
    UserDTO result = userDTO.convertFor(saveResultUser);
    return result;
}
private void checkDTOParams(BindingResult bindingResult){
    if(bindingResult.hasErrors()){
        //throw new 带验证码的验证错误异常 
    }
}

BindingResult is a result set after the Spring MVC validation DTO, spring can refer to the official documentation ( http://spring.io/ ).

After checking the parameters, you can throw a "band verification code validation error exception" can refer to how specific abnormalities design elegant design Java exception ( http://lrwinx.github.io/2016/04/28/ how elegant design java exception / ).

Embrace lombok

Top of the DTO code, has made me look tired, and I believe the reader, too, to see so many Getter and Setter methods, too irritable, then there any way to simplify it.

Please embrace lombok, it will help us solve some of the problems we very upset

Remove Setter and Getter

In fact, this title, I do not want to say too much because of the Internet, but because many people told me that they did not know the existence of lombok, so in order to give readers a better learning, I am willing to write such an example:

@Setter
@Getter
public class UserDTO {
    @NotNull
    private String username;
    @NotNull
    private int age;
    public User convertToUser(){
        UserDTOConvert userDTOConvert = new UserDTOConvert();
        User convert = userDTOConvert.convert(this);
        return convert;
    }
    public UserDTO convertFor(User user){
        UserDTOConvert userDTOConvert = new UserDTOConvert();
        UserDTO convert = userDTOConvert.reverse().convert(user);
        return convert;
    }
    private static class UserDTOConvert extends Converter<UserDTO, User> {
        @Override
        protected User doForward(UserDTO userDTO) {
            User user = new User();
            BeanUtils.copyProperties(userDTO,user);
            return user;
        }
        @Override
        protected UserDTO doBackward(User user) {
            throw new AssertionError("不支持逆向转化方法!");
        }
    }
}

See, annoying Getter and Setter methods have been removed.

However, the example above is not enough to reflect the strong lombok. I want to write some of the Internet is difficult to find, or very few people were using lombok instructions and the instructions on the semantics of the program in use.

For example: @ Data, @ AllArgsConstructor, @ NoArgsConstructor ... these I will not be setting them out, please seek information on their own.

The chain-style bean

What is a chain style I give you an example, look at the following Student of bean?:

public class Student { 
 private String name; 
 private int age; 
 public String getName() { 
	return name; 
 } 
 public Student setName(String name) { 
	 this.name = name; 
	 return this; 
 } 
 public int getAge() { 
	return age; 
 } 
 public Student setAge(int age) { 
	return this; 
 } 
} 

A closer look at the set method, such a setting is the chain's style, when invoked, you can use:

Student student = new Student() 
 .setAge(24) 
 .setName("zs"); 

I believe the rational use of such a chain code will be more programs to bring good readability, look at that if you use lombok to improve it, please use @Accessors (chain = true), look at the following code:

@Accessors(chain = true) 
@Setter 
@Getter 
public class Student { 
 private String name; 
 private int age; 
} 

This completes a very friendly terms for the bean chain operations.

Static constructor

Semantics and the degree of simplification static constructor actually higher than directly to a new object. For example, a new List object, past use is this:

List<String> list = new ArrayList<>(); 

Look at the way to create guava in:

List<String> list = Lists.newArrayList(); 

It lists a naming convention (saying: convention over configuration), it refers to a tool Lists List class of this class, the use of tools to generate List List, this is not a semantic than a new direct child class to the more direct, the answer is yes, then if there is such a tool class called Maps, if you think it's a way to create a Map:

HashMap<String, String> objectObjectHashMap = Maps.newHashMap(); 

Well, if you understand what I said semantics, then you have to become Java programmers a step closer.

Student's just go back and look, a lot of the time, we went to write this Student bean, he will have some input fields, such as name fields Student in the way the general process is to package name field into a constructor, only this passed in the constructor's name, in order to create a Student object.

Constructor connected static constructor parameters and will pass the upper side, will be changed to use the following wording lombok (@RequiredArgsConstructor and @NonNull):

@Accessors(chain = true) 
@Setter 
@Getter 
@RequiredArgsConstructor(staticName = "ofName") 
public class Student { 
 @NonNull private String name; 
 private int age; 
} 

Test code:

Student student = Student.ofName("zs"); 

Such a construct semantic bean whether a constructor parameter containing (comprising the constructor name) is much better than direct new.

Of course, after reading a lot of source code, I would like to believe that the static constructor will first of ofName into more concise:

@Accessors(chain = true) 
@Setter 
@Getter 
@RequiredArgsConstructor(staticName = "of") 
public class Student { 
 @NonNull private String name; 
 private int age; 
} 

Test code:

Student student = Student.of("zs"); 

Of course, he is still chained calls of support:

Student student = Student.of("zs").setAge(24); 

Such write code, is really very simple, and very readable.

Use builder

Builder mode I do not wish to explain, readers can look at the "Head First" (Design mode) of the builder pattern.

In fact, to say that today is a variant of the model builder, and that is to build the bean builder mode, in fact, the main idea is to bring everyone together to look at what brought us lombok.

Look at the state of the original builder of this class Student:

public class Student { 
 private String name; 
 private int age; 
 public String getName() { 
	return name; 
 } 
 public void setName(String name) { 
	this.name = name; 
 } 
 public int getAge() { 
	return age; 
 } 
 public void setAge(int age) { 
	this.age = age; 
 } 
 public static Builder builder(){ 
	return new Builder(); 
 } 
 public static class Builder{ 
 private String name; 
 private int age; 
 public Builder name(String name){ 
	 this.name = name; 
	 return this; 
 } 
 public Builder age(int age){ 
	 this.age = age; 
	 return this; 
 } 
 public Student build(){ 
	 Student student = new Student(); 
	 student.setAge(age); 
	 student.setName(name); 
	 return student; 
 } 
 } 
} 

Invocation:

Student student = Student.builder().name("zs").age(24).build(); 

This builder codes, I was sick and then I'm going to refactor this code with the lombok:

@Builder 
public class Student { 
 private String name; 
 private int age; 
} 

Invocation:

Student student = Student.builder().name("zs").age(24).build(); 

Proxy mode

As we know, in the program interface to call the rest it is a common behavior action, if you're like me used RestTemplate spring, I believe you and I, like, for he throws an exception hated non-http status code.

So we will consider the most RestTemplate underlying wrapper wrapper design patterns:

public abstract class FilterRestTemplate implements RestOperations { 
 protected volatile RestTemplate restTemplate; 
 protected FilterRestTemplate(RestTemplate restTemplate){ 
 this.restTemplate = restTemplate; 
 } 
 //实现RestOperations所有的接口 
} 

Then by the extension of the packaging FilterRestTemplate extension:

public class ExtractRestTemplate extends FilterRestTemplate { 
 private RestTemplate restTemplate; 
 public ExtractRestTemplate(RestTemplate restTemplate) { 
	 super(restTemplate); 
	 this.restTemplate = restTemplate; 
 } 
 public <T> RestResponseDTO<T> postForEntityWithNoException(String url, Object request, Class<T> responseType, Object... uriVariables) 
 throws RestClientException { 
	 RestResponseDTO<T> restResponseDTO = new RestResponseDTO<T>(); 
	 ResponseEntity<T> tResponseEntity; 
	 try { 
		 tResponseEntity = restTemplate.postForEntity(url, request, responseType, uriVariables); 
		 restResponseDTO.setData(tResponseEntity.getBody()); 
		 restResponseDTO.setMessage(tResponseEntity.getStatusCode().name()); 
		 restResponseDTO.setStatusCode(tResponseEntity.getStatusCodeValue()); 
	 }catch (Exception e){ 
		 restResponseDTO.setStatusCode(RestResponseDTO.UNKNOWN_ERROR); 
		 restResponseDTO.setMessage(e.getMessage()); 
		 restResponseDTO.setData(null); 
	 } 
	 return restResponseDTO; 
 } 
} 

Wrapper ExtractRestTemplate perfect throw of abnormal behavior changed, so that the program more fault tolerant. Here we do not consider ExtractRestTemplate complete the function, let's focus on FilterRestTemplate, "RestOperations all interfaces to achieve," This operation is definitely not half past one will be finished, when the reconstruction before I wrote almost half hours, as follows:

public abstract class FilterRestTemplate implements RestOperations { 
 protected volatile RestTemplate restTemplate; 
 protected FilterRestTemplate(RestTemplate restTemplate) { 
	this.restTemplate = restTemplate; 
 } 
 @Override 
 public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { 
	return restTemplate.getForObject(url,responseType,uriVariables); 
 } 
 @Override 
 public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { 
	return restTemplate.getForObject(url,responseType,uriVariables); 
 } 
 @Override 
 public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException { 
	return restTemplate.getForObject(url,responseType); 
 } 
 @Override 
 public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { 
	return restTemplate.getForEntity(url,responseType,uriVariables); 
 } 
 //其他实现代码略。。。 
} 

I'm sure you read the above code, you would like me feel nausea, but then I use lombok provide proxy notes optimize my code (@Delegate):

@AllArgsConstructor 
public abstract class FilterRestTemplate implements RestOperations { 
 @Delegate 
 protected volatile RestTemplate restTemplate; 
}

These lines of code above entirely replace those lengthy code.

It is not very simple, make a lombok programmer hug.

Reconstruction

Demand Case

Project requirements

Project development phase, there is a demand on orders shipped: If orders before 15:00 today, so the delivery time is tomorrow, if the orders after 15 o'clock today, so the delivery time is acquired, if determined time is Sunday, so at this time plus 1 day delivery time.

Reflection and Reconstruction

I believe that this demand appears to be very simple, no matter how writing can be done.

Many people may see this demand, we began to write on the hands or Calendar Date is calculated to complete the requirements.

And my suggestion is to carefully consider how to write code, and then go to write, not to say that all the time operations with Calendar or Date to solve, have to look at the scene.

For the calculation of the time we have to consider joda-time calculation of such similar maturity time frame to write the code, it will make the code more concise and readable.

The reader needs to consider how to use the Java code completion, or do you think the first to write a complete code of this idea, I look at the code below, so that your harvest will be some more:

final DateTime DISTRIBUTION_TIME_SPLIT_TIME = new DateTime().withTime(15,0,0,0); 
private Date calculateDistributionTimeByOrderCreateTime(Date orderCreateTime){ 
 DateTime orderCreateDateTime = new DateTime(orderCreateTime); 
 Date tomorrow = orderCreateDateTime.plusDays(1).toDate(); 
 Date theDayAfterTomorrow = orderCreateDateTime.plusDays(2).toDate(); 
 return orderCreateDateTime.isAfter(DISTRIBUTION_TIME_SPLIT_TIME) ? wrapDistributionTime(theDayAfterTomorrow) : wrapDistributionTime(tomorrow); 
} 
private Date wrapDistributionTime(Date distributionTime){ 
 DateTime currentDistributionDateTime = new DateTime(distributionTime); 
 DateTime plusOneDay = currentDistributionDateTime.plusDays(1); 
 boolean isSunday = (DateTimeConstants.SUNDAY == currentDistributionDateTime.getDayOfWeek()); 
 return isSunday ? plusOneDay.toDate() : currentDistributionDateTime.toDate() ; 
} 

Read this code, you will find that I will judge the different results and are likely to arise as a variable, and ultimately make a ternary operator returns manner, such elegance and readability is obvious, of course, such a code is not easy, I optimized the above code generated three times. Readers can write code and I compared according to their code.

Improve methods

If you do a 3-year + programmer, I like to believe that as such needs, you easily can be done, but if you want to write a Java programmer, you just put your thinking and reconstruction of the code.

Writing code is like writing the same, the same word, we all write, but write good-looking whether it might not be. If you want to write a program, we must constantly thinking and reconstruction, dare to try, dare to innovate, do not follow the beaten track, we must make a good Java programmer.

The best way to raise the level of the code is structured reconstruction (Note: the reconstruction is organized)!

Design Patterns

Design model is the tool, not to mention if you are a current index of high-level programmers.

I often see a certain programmer excited shouting, which points which program I use design patterns, how to write how good, how much good. I am careful to read the time, but found many of them are over-designed.

Business-driven technology or technology-driven business

Business-driven technology or technology-driven business? In fact, this has been a topic of debate, but many people do not think so, I think that we do not want to admit it. What I think is probably analyze as a Java programmer, how should we judge their own in place.

Business-driven technology: If you project where the income is a little or even no income items, please do not engage in other innovative things, do not drive how to how to do business, but to be familiar with what the business is now pain point is how to? help profitability or let the project better and more smoothly carried out.

Technology-driven business: If the item you are in a cattle project, such as Taobao this kind of project, in case I can meet business needs, and business communication, what kind of technology can better help businesses generate revenue , for example at a single time to get into the queue, maybe a few minutes to process the order status is completed, but the user will have a better experience, earn more traffic, then I am willing to believe that business is technology-driven, will agree latency issues orders, so is technology-driven business.

I still believe that most people are in the right direction, business-driven technology.

So since you can not drive the business, then please embrace business change it.

Code design

Been doing Java back end of the project, often there will be some changes, I believe we have encountered.

For example, when we write a piece of code, we consider the mapping requirements into state code pattern, suddenly one day, inside the state mode has added a lot of things change in behavior, this time you are scratching their heads, and you will abruptly state mode add excessive behavior and change.

Slowly you will find that these state mode is actually more like a cluster algorithm should use the strategy pattern, then you should have been confusing.

Having said that, I mean, as long as you feel is reasonable, you set the status bar mode to mode strategy, all the models are not fanciful, are based on reconstruction.

Java programming is no silver bullet, please embrace business change, been thinking about reconstruction, you have a better code design!

You really do good?

I am sorry, I took a title so boring.

A popular foreign programming mode, called pair programming, I believe that many domestic companies do not do so, I will not tell the junction of the benefits brought by the program, in fact, while code review, a process while improving with each other. Since it can not do this, then how to make their living in their own world continue to improve it?

"Usually when developing code to make and believe that is correct, but the wording is perfect." I believe this is the majority of people's voices, but also back to the question of just how to constantly improve it in their own world ?

The answer is:

  • See more mature source framework
  • Looking back at the multi-code
  • Diligent reconstruction
    you really good? If you have completed a week learning source Looking back at the code, and then diligent reconstruction, I think you're a really good.

Maybe you even if only just started, but always insisted, you're really a programmer to write a java code.

skill

UML

UML do not want to discuss relevant knowledge, but I think if you really write Java, please learn to express themselves, UML is the language you speak, do a good Java programmer, please learn at least two UML diagrams:

  • Class Diagram
  • Timing diagram

clean code

I think keep it simple and readable code is essential to ensure that the code, if one day in order to reduce the efficiency of the program and these two points, I think it is understandable, in addition, there is no reason you can make any squander your code.

Readers can look at Robert C. Martin, published "Clean Code" (Code tidy road) book

In any case, please keep your code clean.

Linux basic commands

This, in fact, and will write Java does not matter, but Linux does carry a lot of time running Java containers, please learn the basic commands of Linux.

Daily benefits

No public concern: " Java confidant " send " 1024 " to receive a free 30 classic programming books . Progress with 100,000 programmers. Java knowledge is updated daily Oh, look forward to your arrival!

Java confidant

Guess you like

Origin blog.csdn.net/feilang00/article/details/94737179