Laboratory 2
SSD
Topics:
Clean Code
Refactoring
Clean code
Reference
Robert C Martin
Why do we need clean code???
Programmer
Chef
Writing code
Cooking
Writing code
Cooking
The only way to go
is to go
The only way to go
is to go
FAST
WELL
How to measure?
Code Quality
“Always leave the code you are editing better than you found it.”
Robert C. Martin (Uncle Bob)
RULE
What is Clean code?
Names
Names communicate
means what it says
says what it means!
and
Names - meaningful
int d;
int dd; //days past since project start
int m; //minutes
int daysRemaining;
int daysSinceProjectStart;
int elapsedMinutes;
Names - pronounceable
class DfKndSrv {
private String ord_num;
private int prq;
public String descOrdDet() {
return String.format("Order Number: %s, product Quantity: %s\n", ord_num, prq);
}
}
class DefaultCustomerService {
private String orderNumber;
private int productQuantity;
public String describeOrder() {
return String.format("Order Number: %s, " +
"product Quantity: %s\n",
orderNumber, productQuantity);
}
}
Names - avoid encodings
int i_days;
Address addressString;
//type changed but name did not!
String s_desc;
int days;
Address address;
String description;
Names - intent
int d;
int dd; //days past since project start
int m; //minutes
int daysRemaining;
int daysSinceProjectStart;
int elapsedMinutes;
Scope rule - variables
Short scoped variables should have short names:
Public scoped variables should have long, self-explanatory names:
for (String n : names) {
System.out.println(n.length() + "." + n);
}
public static final String PROJECT_PLUGINS_PATH = "path/to/plugins";
Scope rule - methods
Private methods should have long, descriptive names:
Public methods, oftenly used, should have short names:
private ArrayList<Person> keepOnlyOveragePeople(List<Person> people)
private Student findStudentByNameAndAgeGreaterThan25AndGenderMale(String name)
public interface ProjectRepository {
Project search(String projectID);
Project create(String projectID, String projectPath);
}
Parts of speech rule
Classes / Variables should be nouns:
Booleans should be predicates / adjectives:
Methods should be written like actions:
Enums should be adjectives:
public class Person { private String firstName; private int age; private Status status;}
public class Person { private boolean overage; public boolean isOverage() {return overage;}}
public Person searchByName(String name), public void createWeatherReport(City city),
public int generateRandomNumber(Range range)
enum Level { LOW, MEDIUM, HIGH }, enum ActivityStatus { ACTIVE, PASSIVE, RETIRED}
“Any fool can write code the computer would understand,
but it takes a good programmer to write code a human can understand.”
Martin Fowler, author of Refactoring, Improving the Design of Existing Code
Functions
Functions should be short
5-7
Lines of Code
Lost?
Names
Exactly one thing
Function arguments
No Arguments:
1 or 2 Args is OK
3 Arguments...
4+ Arguments...
No output arguments
public void computeResult(long x, long y, Result result) {
//...some code
result.setResult(x + y);
}
public Result computeResult(long x, long y) {
//...some code
return new Result(x + y);
}
No boolean arguments
public void doSomething(String someString, boolean up) {
//...some code
if (up) {
//...do some stuff
} else {
//...do some other stuff
}
}
2 Things!!!
No boolean arguments
public void doSomething(String someString, boolean up) {
//...some code
if (up) {
//...do some stuff
} else {
//...do some other stuff
}
}
public void doSomeStuff(String someString) {
//...do some stuff
}
2 Things!!!
public void doSomeOtherStuff(String someString) {
//...do some other stuff
}
Comments
Usually noisy
/**
* Gets notification.
*
* @param customer customer
* @param id notification id
* @return the notification for the given customer and notification id.
*/
Optional<NotificationModel> getNotification(CustomerModel customer, String id);
Crazy
// the name
public static String name;
// the address
public static Address address;
// the phone number
public static Phone phoneNumber;
Delete commented Code
public int getNumberOfFilesInProject(String projectID) {
return findProject(projectID)
.map(project -> project.getFiles().size())
.orElse(-1);
// Optional<Project> optionalProject = findProject(projectID);
// if(optionalProject.isPresent()) {
// Project project = optionalProject.get();
// return project.getFiles().size();
// }
//
// return -1;
}
Delete commented Code
public int getNumberOfFilesInProject(String projectID) {
return findProject(projectID)
.map(project -> project.getFiles().size())
.orElse(-1);
// Optional<Project> optionalProject = findProject(projectID);
// if(optionalProject.isPresent()) {
// Project project = optionalProject.get();
// return project.getFiles().size();
// }
//
// return -1;
}
Delete commented Code
public int getNumberOfFilesInProject(String projectID) {
return findProject(projectID)
.map(project -> project.getFiles().size())
.orElse(-1);
// Optional<Project> optionalProject = findProject(projectID);
// if(optionalProject.isPresent()) {
// Project project = optionalProject.get();
// return project.getFiles().size();
// }
//
// return -1;
}
Classes
One responsibility
Refactoring
How do you make sure you did not break anything?
Example
Why should we refactor?
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
ArrayList<Person> personList = new ArrayList<>();
ArrayList<String> stringList = new ArrayList<>();
for (Person person : people) {
int x = person.getAge();
if (x >= 18) {
personList.add(person);
}
}
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
What does the
getPeopleNames()
method do?
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
ArrayList<Person> personList = new ArrayList<>();
ArrayList<String> stringList = new ArrayList<>();
for (Person person : people) {
int x = person.getAge();
if (x >= 18) {
personList.add(person);
}
}
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
Did you get it?
What does the
getPeopleNames()
method do?
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class PersonService {
public List<String> getOveragePeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
printNames(overagePeopleNames);
return overagePeopleNames;
}
...
}
What does the
getPeopleNames()
method do?
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class PersonService {
public List<String> getOveragePeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
printNames(overagePeopleNames);
return overagePeopleNames;
}
...
}
COD
kB
Rename
COD
kB
Renaming
Shift + F6 -> Rename Field, Variable, Method, Class, File, Package, Project
Extracting
Ctrl + Alt + C -> Constant
Ctrl + Alt + V -> Variable
Ctrl + Alt + F -> Field
Ctrl + Alt + M -> Method
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
ArrayList<Person> personList = new ArrayList<>();
ArrayList<String> stringList = new ArrayList<>();
for (Person person : people) {
int x = person.getAge();
if (x >= 18) {
personList.add(person);
}
}
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
ArrayList<Person> personList = new ArrayList<>();
ArrayList<String> stringList = new ArrayList<>();
for (Person person : people) {
int x = person.getAge();
if (x >= 18) {
personList.add(person);
}
}
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
ArrayList<Person> personList = new ArrayList<>();
ArrayList<String> stringList = new ArrayList<>();
for (Person person : people) {
int x = person.getAge();
if (x >= 18) {
personList.add(person);
}
}
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
private ArrayList<Person> keepOnlyOveragePeople
(List<Person> people) {
ArrayList<Person> overagePeople = new ArrayList<>();
for (Person person : people) {
if (person.getAge() >= 18) {
overagePeople.add(person);
}
}
return overagePeople;
}
Ctrl + Alt + M
Extract Method
List<Person> personList =
keepOnlyOveragePeople(people);
transformed to
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> personList = keepOnlyOveragePeople(people);
ArrayList<String> stringList = new ArrayList<>();
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> personList = keepOnlyOveragePeople(people);
ArrayList<String> stringList = new ArrayList<>();
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
Shift + F6
Rename
List<Person> overagePeople =
keepOnlyOveragePeople(people);
renamed to
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
ArrayList<String> stringList = new ArrayList<>();
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
ArrayList<String> stringList = new ArrayList<>();
for (int i = 0; i < personList.size(); i++) {
Person p = personList.get(i);
String s1 = p.getFirstName() + " " + p.getLastName();
stringList.add(s1);
}
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
private ArrayList<String> getPeopleFullNames
(List<Person> overagePeople) {
ArrayList<String> stringList = new ArrayList<>();
for (Person s : overagePeople) {
stringList.add(s.getFirstName() +
" " + s.getLastName());
}
return stringList;
}
Ctrl + Alt + M
Extract Method
List<String> stringList =
getPeopleFullNames(overagePeople);
transformed to
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> personList = keepOnlyOveragePeople(people);
List<String> stringList = getPeopleFullNames(overagePeople);
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
Shift + F6
Rename
List<String> overagePeopleNames =
getPeopleFullNames(overagePeople);
renamed to
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames =
getPeopleFullNames(overagePeople);
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames =
getPeopleFullNames(overagePeople);
for (int i = 0; i < stringList.size(); i++) {
for (int j = i; j < stringList.size(); j++) {
if (stringList.get(i).compareToIgnoreCase(stringList.get(j)) > 0) {
String aux = stringList.get(j);
stringList.set(j, stringList.get(i));
stringList.set(i, aux);
}
}
}
for (String s : stringList) System.out.println(s);
return stringList;
}
}
private List<String> sortNamesAlphabetically(List<String> names) {
List<String> sortedNames = new ArrayList<>(names);
for (int i = 0; i < sortedNames.size(); i++)
for (int j = i; j < sortedNames.size(); j++)
if (sortedNames.get(i).compareToIgnoreCase(sortedNames.get(j)) > 0) {
String aux = sortedNames.get(j);
sortedNames.set(j, sortedNames.get(i));
sortedNames.set(i, aux);
}
return sortedNames;
}
Ctrl + Alt + M
Extract Method
overagePeopleNames =
sortNamesAlphabetically(overagePeopleNames);
transformed to
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
for (String s : stringList) System.out.println(s);
return stringList;
}
}
public class Manager {
public List<String> getPeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
for (String s : stringList) System.out.println(s);
return stringList;
}
}
private void printNames(List<String> names) {
for (String name : names)
System.out.println(name);
}
Ctrl + Alt + M
Extract Method
printNames(overagePeopleNames);
transformed to
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
}
public enum Status {
SINGLE,
MARRIED,
DIVORCED,
WIDOW
}
public class PersonService {
public List<String> getOveragePeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
printNames(overagePeopleNames);
return overagePeopleNames;
}
...
}
private ArrayList<String> getPeopleFullNames(List<Person> overagePeople) {
ArrayList<String> stringList = new ArrayList<>();
for (Person s : overagePeople) {
stringList.add(s.getFirstName() + " " + s.getLastName());
}
return stringList;
}
private ArrayList<String> getPeopleFullNames(List<Person> overagePeople) {
ArrayList<String> stringList = new ArrayList<>();
for (Person s : overagePeople) {
stringList.add(s.getFirstName() + " " + s.getLastName());
}
return stringList;
}
private ArrayList<String> getPeopleFullNames(List<Person> overagePeople) {
ArrayList<String> stringList = new ArrayList<>();
for (Person s : overagePeople) {
stringList.add(s.getFirstName() + " " + s.getLastName());
}
return stringList;
}
Ctrl + Alt + M
Extract Method
stringList.add(getFullName(s));
becomes
private String getFullName(Person s) {
return s.getFirstName() + " " + s.getLastName();
}
private ArrayList<String> getPeopleFullNames(List<Person> overagePeople) {
ArrayList<String> stringList = new ArrayList<>();
for (Person s : overagePeople) {
stringList.add(s.getFirstName() + " " + s.getLastName());
}
return stringList;
}
Ctrl + Alt + M
Extract Method
stringList.add(getFullName(s));
becomes
private String getFullName(Person s) {
return s.getFirstName() + " " + s.getLastName();
}
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
String getFullName() {
return getFirstName() + " " + getLastName();
}
}
F6
Move Instance Method
stringList.add(s.getFullName());
becomes
public class PersonService {
public List<String> getOveragePeopleNames(List<Person> people) {
List<Person> overagePeople = keepOnlyOveragePeople(people);
List<String> overagePeopleNames = getPeopleFullNames(overagePeople);
overagePeopleNames = sortNamesAlphabetically(overagePeopleNames);
printNames(overagePeopleNames);
return overagePeopleNames;
}
...
}
public class Person {
private String firstName;
private String lastName;
private int age;
private Status status;
//constructor, getters, setters
String getFullName() {
return getFirstName() + " " + getLastName();
}
}
Null checks
public class Project {
private String id;
private String name;
private List<Author> authors;
private List<Commit> commits;
private List<File> files;
//constructor, getters, setters
}
public class Author {
private String name;
private String email;
private List<Commit> commits;
//constructor, getters, setters
}
public class Commit {
private String name;
private Date date;
private Author author;
//constructor, getters, setters
}
public class File {
private String path;
private String name;
private String extension;
//constructor, getters, setters
}
public class NoSuchProjectException extends RuntimeException {
public NoSuchProjectException(String projectID) {
super(String.format("The project with id %s " +
"does not exist!", projectID));
}
}
public interface ProjectRepository {
Project getProjectByID(String projectID);
}
public class ProjectService {
private ProjectRepository projectRepository; // setters
private Project findProject(String projectID) {
return projectRepository.getProjectByID(projectID);
}
//rest of methods...
}
public int getNumberOfFilesInProject
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public String getFirstAuthorNameForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
return project.getCommits().get(0)
.getAuthor().getName();
}
public void printProjectDetails
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName());
}
}
public List<String> getCommitNamesForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
public int getNumberOfFilesInProject
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public String getFirstAuthorNameForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
return project.getCommits().get(0)
.getAuthor().getName();
}
public void printProjectDetails
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName());
}
}
public List<String> getCommitNamesForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
java.util.Optional<T>
Optional
2 Possible States
Present
Empty (absent)
Basic Operations
Basic Rules
More information: https://www.youtube.com/watch?v=Ej0sss6cq14
Rule #1
Never, ever, use null for an Optional value or return value
public Optional<String> getSomeString() {
//...some Code
if (someCondition())
return null;
//...some Code
}
public Optional<String> getSomeString() {
//...some Code
if (someCondition())
return Optional.empty();
//...some Code
}
Optional<Integer> optionalInteger = null;
Optional<Integer> optionalInteger =
Optional.empty();
Rule #2
Never use Optional.get() unless you can prove that the Optional is present
public void doSomething() {
//...
Optional<String> stringOptional = getSomeOptional();
stringOptional.get();
//...
}
public void doSomething() {
//...
Optional<String> stringOptional = getSomeOptional();
if (stringOptional.isPresent()) {
stringOptional.get();
}
//...
}
Interested?
public int getNumberOfFilesInProject
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public String getFirstAuthorNameForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
return project.getCommits().get(0)
.getAuthor().getName();
}
public void printProjectDetails
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName());
}
}
public List<String> getCommitNamesForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
public int getNumberOfFilesInProject
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public String getFirstAuthorNameForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
return project.getCommits().get(0)
.getAuthor().getName();
}
public void printProjectDetails
(String projectID) {
Project project = findProject(projectID);
if (project != null) {
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName());
}
}
public List<String> getCommitNamesForProject
(String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
private Project findProject(String projectID) {
return projectRepository.getProjectByID(projectID);
}
Use Optional...
private Project findProject(String projectID) {
return projectRepository.getProjectByID(projectID);
}
private Optional<Project> findProject(String projectID) {
Project project = projectRepository.getProjectByID(projectID);
if (project == null)
return Optional.empty();
return Optional.of(project);
}
private Project findProject(String projectID) {
return projectRepository.getProjectByID(projectID);
}
private Optional<Project> findProject(String projectID) {
Project project = projectRepository.getProjectByID(projectID);
if (project == null)
return Optional.empty();
return Optional.of(project);
}
private Optional<Project> findProject(String projectID) {
Project project = projectRepository.getProjectByID(projectID);
return Optional.ofNullable(project);
}
public List<String> getCommitNamesForProject (String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
public List<String> getCommitNamesForProject(String projectID) {
Project project = findProject(projectID)
.orElseThrow(() -> new NoSuchProjectException(projectID));
List<String> commitNames = new ArrayList<>();
for (Commit commit : project.getCommits()) {
commitNames.add(commit.getName());
}
return commitNames;
}
public String getFirstAuthorNameForProject (String projectID) {
Project project = findProject(projectID);
if (project == null) {
throw new NoSuchProjectException(projectID);
}
return project.getCommits().get(0).getAuthor().getName();
}
public String getFirstAuthorNameForProject(String projectID) {
Project project = findProject(projectID)
.orElseThrow(() -> new NoSuchProjectException(projectID));
return project.getCommits().get(0).getAuthor().getName();
}
public void printProjectDetails (String projectID) {
Project project = findProject(projectID);
if (project != null) {
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName());
}
}
public void printProjectDetails(String projectID) {
findProject(projectID).ifPresent(project ->
System.out.printf("Project ID: %s\n
Project name: %s",
project.getId(), project.getName()));
}
public int getNumberOfFilesInProject (String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public int getNumberOfFilesInProject(String projectID) {
Optional<Project> optionalProject = findProject(projectID);
if(optionalProject.isPresent()) {
Project project = optionalProject.get();
return project.getFiles().size();
}
return -1;
}
Really???
public int getNumberOfFilesInProject (String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public int getNumberOfFilesInProject(String projectID) {
Optional<Project> optionalProject = findProject(projectID);
if(optionalProject.isPresent()) {
Project project = optionalProject.get();
return project.getFiles().size();
}
return -1;
}
public int getNumberOfFilesInProject (String projectID) {
Project project = findProject(projectID);
if (project != null) {
return project.getFiles().size();
}
return -1;
}
public int getNumberOfFilesInProject(String projectID) {
Optional<Project> optionalProject = findProject(projectID);
if(optionalProject.isPresent()) {
Project project = optionalProject.get();
return project.getFiles().size();
}
return -1;
}
Rule #3
Rule #3
Prefer alternatives to Optional.isPresent() and Optional.get()
public void doSomething() {
//...
Optional<String> stringOptional = getSomeOptional();
if (stringOptional.isPresent()) {
stringOptional.get();
}
//...
}
Optional Map operation
Burger with meat
Burger with fries
Optional<M>
Optional<F>
map
Optional Map operation
Optional<Person>
Optional<String>
map
Optional<Person> optionalPerson = Optional.empty();
Optional<String> firstNameOptional = optionalPerson
.map(person -> person.getFirstName());
public int getNumberOfFilesInProject(String projectID) {
Optional<Project> optionalProject = findProject(projectID);
if(optionalProject.isPresent()) {
Project project = optionalProject.get();
return project.getFiles().size();
}
return -1;
}
public int getNumberOfFilesInProject(String projectID) {
return findProject(projectID)
.map(project -> project.getFiles().size())
.orElse(-1);
}
IntelliJ IDEA Refactoring Shortcuts
Shift + F6 | Rename |
Ctrl + Alt + C | Extract Constant |
Ctrl + Alt + V | Extract Variable |
Ctrl + Alt + F | Extract Field |
Ctrl + Alt + M | Extract Method |
Ctrl + Alt + N | Inline variable / method |
Alt + Delete | Safe Delete |
Ctrl + Alt + L | Reformat Code |
| |
Alt + Enter | Smart Suggestions |
References
Hands-On