Design Patterns SAGA #4: Real Project Situations With Prototype

The Problem: We could solve the Prototype problem in an easy way, but we would have to write several setters and create a converter that passes all the information from getter to setter. For example:

newContract.setId(contract.getId());
newContract.setName(contract.getName());

We can’t assign the object reference because both variables will be pointing to the same object. If I change one of the references both references will be identical.

contract = newContract;
contract.setName("It's the same object reference!");

Both references will be the same value. The reference variable newContract.getName() will return “It’s the same object reference!”.

What would be a real world situation in which the Prototype Pattern could be used? We can use it for logging, for example. In order to keep the old state and get the new state of the object, we must use the Prototype Pattern. We can’t copy the reference and use the same object. Another situation would be when we must copy information from an entity and save the same information using JPA.

So, how do you prefer doing the object copy? By manual setters? By using Reflection methods? Or using the clone method from Java API? I will show you the possible ways to solve this problem. I prefer the clone() method!

The diagram:

prototype_diagram.PNG

Get the source code:
https://github.com/rafadelnero/design-patterns-saga.git

1 – The Contract POJO: The first thing we have to realize is that this class is implementing Cloneable. The second thing is that we are overriding the clone() method. We are also changing clone() visibility to “public“.

On the clone() method, we reference the super class cloning the object like this:

clonedContract = (Contract) super.clone();

Unfortunately, the interface Cloneable was implemented in Java 1.0 where generics didn’t exist yet. As a consequence, we need to use class casting.

Shallow Copy vs. Deep Copy: On the below example, we are using Deep Copy. This means we are making a copy with all the related objects inside the Contract class. See that we are doing it manually:

clonedContract.contractComplement = (ContractComplement) contractComplement.clone();

We are copying also the ContractComplement class. An example of Shallow Copy is pretty simple. We just have to copy the Contract class.

public class Contract implements Cloneable {

	private long id;

	private String name;

	private ContractComplement contractComplement;

	private BigDecimal price;

	public Contract(long id, String name,
			ContractComplement contractComplement, BigDecimal price) {
		this.id = id;
		this.name = name;
		this.contractComplement = contractComplement;
		this.price = price;
	}

	public Contract() {
		super();
	}

	@Override
	protected Object clone() {
		Contract clonedContract;
		try {
			clonedContract = (Contract) super.clone();
			clonedContract.contractComplement = (ContractComplement) contractComplement.clone();
			return clonedContract;
		} catch (CloneNotSupportedException e) {
			throw new RuntimeException(e);
		}
	}

	// Getters and Setters omitted

}

2 – The ContractComplement class: There is no new concept here. We just implemented the Cloneable interface and overrode the clone() method using the super.clone() method to clone this object.

public class ContractComplement implements Cloneable {

	private String complementName;

	private Integer specificProductPrice;

	public ContractComplement() {
		super();
	}

	public ContractComplement(String complementName, Integer specificProductPrice) {
		this.complementName = complementName;
		this.specificProductPrice = specificProductPrice;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	// Getters and Setters omitted

}

3 – The Unitary Test: Now we are going to check if the objects are really different and if the values are equal.

checkIfTheObjectWasClonedTest() method: Here we are testing the Prototype Pattern with the clone() method from the Java API. We are checking if the object was successfully cloned.

checkIfTheObjectWasCopiedByBeanUtilsTest: This is an alternative way to solve this problem. We can use the utility class BeanUtils from the Spring dependency. We have to add it to the pom.xml:
        org.springframework
        spring-beans
        4.3.9.RELEASE

There are some cons about using this class:

1 – We must create getters and setters. We can’t encapsulate them.
2 – The copy is done by Reflection. It’s very slow.
3 – We must copy the objects manually.

public class PrototypeTest {

	// Constants omitted.

	@Test
	public void checkIfTheObjectWasClonedTest() {
		Contract contract = mockContract();

		Contract contractPrototype = (Contract) contract.clone();

		checkIfTheObjectsAreCloned(contract, contractPrototype);
	}

	@Test
	public void checkIfTheObjectWasCopiedByBeanUtilsTest() throws IllegalAccessException, InvocationTargetException {
		Contract contract = mockContract();

		Contract contractToBeCopied = new Contract();
		ContractComplement complementContractToBeCopied = new ContractComplement();

		BeanUtils.copyProperties(contract, contractToBeCopied);
		BeanUtils.copyProperties(contract.getContractComplement(), complementContractToBeCopied);

		contractToBeCopied.setContractComplement(complementContractToBeCopied);

		checkIfTheObjectsAreCloned(contract, contractToBeCopied);
	}

	private Contract mockContract() {
		ContractComplement complement = new ContractComplement(COMPLEMENT_NAME, QTD_CUSTOMERS);

		Contract contract = new Contract(ID_CONTRACT, CONTRACT_NAME, complement, CONTRACT_VALUE);
		return contract;
	}

	private void checkIfTheObjectsAreCloned(Contract contract, Contract contractToBeCopied) {
		Assert.assertTrue(contract.getId() == contractToBeCopied.getId());
		Assert.assertTrue(contract.getName().equals(contractToBeCopied.getName()));
		Assert.assertTrue(contract.getPrice().equals(contractToBeCopied.getPrice()));

		ContractComplement complement = contract.getContractComplement();
		ContractComplement copiedComplement = contractToBeCopied.getContractComplement();

		Assert.assertTrue(complement.getComplementName().equals(copiedComplement.getComplementName()));
		Assert.assertTrue(complement.getSpecificProductPrice().equals(copiedComplement.getSpecificProductPrice()));

		Assert.assertFalse(contract.equals(contractToBeCopied));
		Assert.assertFalse(contract.getContractComplement().equals(contractToBeCopied.getContractComplement()));
	}

}

Summary of actions:

1 – Implemented the Cloneable interface.
2 – Overrode the clone() method.
3 – Changed the visibility of the clone() method to public.
4 – Invoked the super.clone() method.
5 – Made a copy of ContractComplement in the clone() method explicitly.

To practice the Prototype Pattern you can create another POJO, implement the Cloneable interface and make the Deep Copy! Try to use TDD (Test Driven Development). Start the development from the test.

Design Patterns SAGA #4: Real Project Situations With Prototype

Java Challenge #9: Tokenizer

It is so important to know that Tokenizer exists and to know what tools you have available to make your code powerful!

Try to solve this challenge before seeing the answer below.

tokenizer.jpg

Answer: This is an easy one. We created the object Scanner passing the String to be tokenized, separated by a pattern. At first, you’ve got to know what the symbols on the tokens mean.

This symbol is called Regex. Many languages use the same concept:
http://www.vogella.com/tutorials/JavaRegularExpressions/article.html

In simple words, this symbol “[^\\w*]” means “not a word” so it will tokenize by the comma “,“.

The result is:
ThisIsIt
theFinalString
NoBugsProject

Java Challenge #9: Tokenizer

Java Challenge #8: Enums Implementing Interfaces

Enums, do you really master them? Can you tell me if it’s going to compile? If not, explain why. If so, write the result.

Try to solve this challenge before seeing the answer below.

enumchallenge.jpg

Answer: The first thing to observe is the implementation of the interface Invoker on the Enum. It’s not very common to do this, but it’s possible. When we access the Enum reference of the reference it does not make a difference. The invokeShenLong() method will be invoked in the same way bringing all the Enums declared on DragonBalls. When we enter in the loop, we are not using brackets ({}) on the “if” command. This means that only one line will be executed.

Conclusion: Until the Enums are equaled, the looping will continue. In the end, the iterated Enums will be FIFTH and equal to one another.

The output will be:
Same dragon ball
FIFTH

Java Challenge #8: Enums Implementing Interfaces

JAVA CHALLENGE #7: Interfaces and Abstract classes

Who is stronger? Master Yoda or Darth Vader? What will the output be? Solve this challenge and find out!

Before seeing the answer below, try it out!

starwarschallenge.jpg

Answer: At first we create an anonymous inner class of Darth Vader, that means any class that implements DarthVader interface. We have only one getNumber() method.

With MasterYoda, things are different. We created an abstract class with the getNumber() method and another one in the inner class of MasterYoda. This is the same as DarthVader, it is an anonymous inner class. This challenge is pretty tricky because you can see that there is a method overloading both methods. Which one will be invoked? See that we are passing a new Integer(FORCE) for the getNumber() method. For this reason, the method from the abstract class will be invoked and MasterYoda will have the force of 20.

The answer is:
30
The stronger Jedi is: Master Yoda

May the force be with you!

JAVA CHALLENGE #7: Interfaces and Abstract classes

Java Challenge #6: Thread Start

Threads! We commonly don’t deal with them directly on day-to-day work. What will the wolverineAdrenaline be?

Try to solve this challenge before seeing the answer below.

wolverineChallenge.jpg

Answer: Remember, Threads execution is always uncertain and depends on the JVM. The order of execution is always random.

Conclusion: There is no exact result. The Threads will be executed randomly. wolverineAdrenaline could be 10, 11, 12, 13 or 14.

Java Challenge #6: Thread Start

Java Challenge #5: Logical and Bitwise Operators

Have you mastered logical operators?

Try to sum these numbers before seeing the answer below.

logical_operators.PNG

Answer: There are some important concepts here. The first concept is the bitwise operators. They will be checked wherever the result is true or false. For example, when we use logical operators like:

/* The second condition won't be executed,
because it's not necessary, once you are
using "&&", both conditions must be "true"
when one of them is false, JVM just ignores the rest. */
if (false && true) {

}

When we use bitwise operators:

/* The second condition will be checked,
even if the first condition is false,
 this can be useful when you want to
execute a command in every situation on your conditions. */
if (false & true) {

}

When we use the command “||” the same rule is applied here. See the example:

/* The second condition won't be
executed because once we are using "||",
if one of the conditions is "true" the
whole condition will be true, so JVM won't
check the next condition. */
if (true || false) {

}

/* When using the bitwise operator,
both conditions will be check,
even if the first condition is "true" */
if (true | false) {

}

We must know the incremental operator. When you use it before the variable it will increment in the line you used it. When you use the post-incremental operator it will increment the next time you use the variable. For example:

/* In the first condition, the variable
"i" will be 5 and on the other will be 6,
so both conditions will be true */
int i = 5;
if (i++ == 5 || i++ == 6) {}

/* In the first condition the variable
will be 6 and in the next will be 7,
so both conditions will be false */
int i = 5;
if (++i == 5 && ++i == 6) {}

Knowing all these concepts, now I can give the answer, it is 74! Try this challenge, debug it, and see the concepts in a practical way. This is how you master a programming language!

Java Challenge #5: Logical and Bitwise Operators

Java Challenge #4: Switch Case

Switch case challenge – what will the result be? Don’t test the code. Answer the question by reading it!

Try to solve this challenge before seeing the answer below.

switch_case.jpg

Answer: “MnNeH”. Pretty easy, huh? But the “switch case” command can be tricky. The formula number of heisenberg is 50, so the second case will be executed until the break of the “case 5”, even if the condition is not true.

Java Challenge #4: Switch Case