BAEL-16653 (#7691)
* added module 'design-patterns-behavioral' * added module 'design-patterns-structural' * added module 'design-patterns-creational' * added module 'design-patterns-architectural' * added module 'design-patterns-functional' * moved facade code examples from design-patterns to design-patterns-structural * moved singleton examples from design-patterns to design-patterns-creational * moved bridge examples from design-patterns to design-patterns-structural * moved creational examples from design-patterns to design-patterns-creational * moved observer examples from design-patterns to design-patterns-behavioral * moved flyweight examples from design-patterns to design-patterns-creational * moved service locator examples from design-patterns to design-patterns-architectural * moved double checked locking singleton examples from design-patterns to design-patterns-creational * moved composite examples from design-patterns to design-patterns-structural * moved visitor examples from design-patterns to design-patterns-behavioral * moved dao examples from design-patterns to design-patterns-architectural * moved interpreter examples from design-patterns to design-patterns-behavioral * moved state examples from design-patterns to design-patterns-behavioral * moved decorator examples from design-patterns to design-patterns-structural * renamed LogerUtil to LoggerUtil * moved template method examples from design-patterns to design-patterns-behavioral * moved chain of responsibility examples from design-patterns to design-patterns-behavioral * moved command examples from design-patterns to design-patterns-behavioral * moved constructor vs static factory method examples from design-patterns to design-patterns-creational * moved adapter examples from design-patterns to design-patterns-structural * moved currying examples from design-patterns to design-patterns-functional * moved proxy examples from design-patterns to design-patterns-structural * moved persistence.xml from design-patterns to design-patterns-architectural * deleted empty module: design-patterns * moved mediator examples from design-patterns-2 to design-patterns-behavioral * moved null object examples from design-patterns-2 to design-patterns-behavioral * moved null check examples from design-patterns to design-patterns-behavioral * moved freebuilder examples from design-patterns-2 to design-patterns-creational * added module design-patterns-behavioral-2 * moved memento examples from design-patterns-2 to design-patterns-behavioral-2 * removed empty module design-patterns-2 * changed http to https in readmes in modules design-patterns-*
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
### Relevant Articles:
|
||||
- [Singletons in Java](https://www.baeldung.com/java-singleton)
|
||||
- [Introduction to Creational Design Patterns](https://www.baeldung.com/creational-design-patterns)
|
||||
- [Abstract Factory Pattern in Java](https://www.baeldung.com/java-abstract-factory-pattern)
|
||||
- [Flyweight Pattern in Java](https://www.baeldung.com/java-flyweight)
|
||||
- [Double-Checked Locking with Singleton](https://www.baeldung.com/java-singleton-double-checked-locking)
|
||||
- [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods)
|
||||
- [Automatic Generation of the Builder Pattern with FreeBuilder](https://www.baeldung.com/java-builder-pattern-freebuilder)
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>design-patterns-creational</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>design-patterns-creational</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>patterns</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.inferred</groupId>
|
||||
<artifactId>freebuilder</artifactId>
|
||||
<version>${freebuilder.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>${javax.annotations.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
|
||||
<freebuilder.version>2.4.1</freebuilder.version>
|
||||
<javax.annotations.version>3.0.2</javax.annotations.version>
|
||||
<assertj-core.version>3.9.1</assertj-core.version>
|
||||
</properties>
|
||||
</project>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.constructorsstaticfactorymethods.application;
|
||||
|
||||
import com.baeldung.constructorsstaticfactorymethods.entities.User;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
User user1 = User.createWithDefaultCountry("John", "john@domain.com");
|
||||
User user2 = User.createWithLoggedInstantiationTime("John", "john@domain.com", "Argentina");
|
||||
User user3 = User.getSingletonInstance("John", "john@domain.com", "Argentina");
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.constructorsstaticfactorymethods.entities;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
|
||||
public class User {
|
||||
|
||||
private static volatile User instance = null;
|
||||
private static final Logger LOGGER = Logger.getLogger(User.class.getName());
|
||||
private final String name;
|
||||
private final String email;
|
||||
private final String country;
|
||||
|
||||
public static User createWithDefaultCountry(String name, String email) {
|
||||
return new User(name, email, "Argentina");
|
||||
}
|
||||
|
||||
public static User createWithLoggedInstantiationTime(String name, String email, String country) {
|
||||
setLoggerProperties();
|
||||
LOGGER.log(Level.INFO, "Creating User instance at : {0}", LocalTime.now());
|
||||
return new User(name, email, country);
|
||||
}
|
||||
|
||||
public static User getSingletonInstance(String name, String email, String country) {
|
||||
if (instance == null) {
|
||||
synchronized (User.class) {
|
||||
if (instance == null) {
|
||||
instance = new User(name, email, country);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
private User(String name, String email, String country) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
private static void setLoggerProperties() {
|
||||
ConsoleHandler handler = new ConsoleHandler();
|
||||
handler.setLevel(Level.INFO);
|
||||
handler.setFormatter(new SimpleFormatter());
|
||||
LOGGER.addHandler(handler);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public interface AbstractFactory<T> {
|
||||
T create(String type) ;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class AbstractPatternDriver {
|
||||
public static void main(String[] args) {
|
||||
AbstractFactory abstractFactory;
|
||||
|
||||
//creating a brown toy dog
|
||||
abstractFactory = FactoryProvider.getFactory("Toy");
|
||||
Animal toy =(Animal) abstractFactory.create("Dog");
|
||||
|
||||
abstractFactory = FactoryProvider.getFactory("Color");
|
||||
Color color =(Color) abstractFactory.create("Brown");
|
||||
|
||||
String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound();
|
||||
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public interface Animal {
|
||||
String getType();
|
||||
String makeSound();
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class AnimalFactory implements AbstractFactory<Animal> {
|
||||
|
||||
@Override
|
||||
public Animal create(String animalType) {
|
||||
if ("Dog".equalsIgnoreCase(animalType)) {
|
||||
return new Dog();
|
||||
} else if ("Duck".equalsIgnoreCase(animalType)) {
|
||||
return new Duck();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class Brown implements Color {
|
||||
|
||||
@Override
|
||||
public String getColor() {
|
||||
return "brown";
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public interface Color {
|
||||
String getColor();
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class ColorFactory implements AbstractFactory<Color> {
|
||||
|
||||
@Override
|
||||
public Color create(String colorType) {
|
||||
if ("Brown".equalsIgnoreCase(colorType)) {
|
||||
return new Brown();
|
||||
} else if ("White".equalsIgnoreCase(colorType)) {
|
||||
return new White();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class Dog implements Animal {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Dog";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String makeSound() {
|
||||
return "Barks";
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class Duck implements Animal {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Duck";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String makeSound() {
|
||||
return "Squeks";
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class FactoryProvider {
|
||||
public static AbstractFactory getFactory(String choice){
|
||||
|
||||
if("Toy".equalsIgnoreCase(choice)){
|
||||
return new AnimalFactory();
|
||||
}
|
||||
else if("Color".equalsIgnoreCase(choice)){
|
||||
return new ColorFactory();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
public class White implements Color {
|
||||
|
||||
@Override
|
||||
public String getColor() {
|
||||
return "White";
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.baeldung.creational.builder;
|
||||
|
||||
public class BankAccount {
|
||||
private String name;
|
||||
private String accountNumber;
|
||||
private String email;
|
||||
private boolean newsletter;
|
||||
|
||||
//The constructor that takes a builder from which it will create object
|
||||
//the access to this is only provided to builder
|
||||
private BankAccount(BankAccountBuilder builder) {
|
||||
this.name = builder.name;
|
||||
this.accountNumber = builder.accountNumber;
|
||||
this.email = builder.email;
|
||||
this.newsletter = builder.newsletter;
|
||||
}
|
||||
|
||||
public static class BankAccountBuilder {
|
||||
private String name;
|
||||
private String accountNumber;
|
||||
private String email;
|
||||
private boolean newsletter;
|
||||
|
||||
//All Mandatory parameters goes with this constructor
|
||||
public BankAccountBuilder(String name, String accountNumber) {
|
||||
this.name = name;
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
//setters for optional parameters which returns this same builder
|
||||
//to support fluent design
|
||||
public BankAccountBuilder withEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BankAccountBuilder wantNewsletter(boolean newsletter) {
|
||||
this.newsletter = newsletter;
|
||||
return this;
|
||||
}
|
||||
|
||||
//the actual build method that prepares and returns a BankAccount object
|
||||
public BankAccount build() {
|
||||
return new BankAccount(this);
|
||||
}
|
||||
}
|
||||
|
||||
//getters
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public boolean isNewsletter() {
|
||||
return newsletter;
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.creational.builder;
|
||||
|
||||
public class BuilderPatternDriver {
|
||||
public static void main(String[] args) {
|
||||
BankAccount newAccount = new BankAccount
|
||||
.BankAccountBuilder("Jon", "22738022275")
|
||||
.withEmail("jon@example.com")
|
||||
.wantNewsletter(true)
|
||||
.build();
|
||||
|
||||
System.out.println("Name: " + newAccount.getName());
|
||||
System.out.println("AccountNumber:" + newAccount.getAccountNumber());
|
||||
System.out.println("Email: " + newAccount.getEmail());
|
||||
System.out.println("Want News letter?: " + newAccount.isNewsletter());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class FactoryDriver {
|
||||
public static void main(String[] args) {
|
||||
Polygon p;
|
||||
PolygonFactory factory = new PolygonFactory();
|
||||
|
||||
//get the shape which has 4 sides
|
||||
p = factory.getPolygon(4);
|
||||
System.out.println("The shape with 4 sides is a " + p.getType());
|
||||
|
||||
//get the shape which has 4 sides
|
||||
p = factory.getPolygon(8);
|
||||
System.out.println("The shape with 8 sides is a " + p.getType());
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class Heptagon implements Polygon {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Heptagon";
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class Octagon implements Polygon {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Octagon";
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class Pentagon implements Polygon {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Pentagon";
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public interface Polygon {
|
||||
String getType();
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class PolygonFactory {
|
||||
public Polygon getPolygon(int numberOfSides) {
|
||||
if(numberOfSides == 3) {
|
||||
return new Triangle();
|
||||
}
|
||||
if(numberOfSides == 4) {
|
||||
return new Square();
|
||||
}
|
||||
if(numberOfSides == 5) {
|
||||
return new Pentagon();
|
||||
}
|
||||
if(numberOfSides == 7) {
|
||||
return new Heptagon();
|
||||
}
|
||||
else if(numberOfSides == 8) {
|
||||
return new Octagon();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class Square implements Polygon {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Square";
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
public class Triangle implements Polygon {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Triangle";
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.creational.singleton;
|
||||
|
||||
public class Singleton {
|
||||
private Singleton() {}
|
||||
|
||||
private static class SingletonHolder {
|
||||
public static final Singleton instance = new Singleton();
|
||||
}
|
||||
|
||||
public static Singleton getInstance() {
|
||||
return SingletonHolder.instance;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.creational.singleton;
|
||||
|
||||
public class SingletonDriver {
|
||||
public static void main(String[] args) {
|
||||
Singleton instance = Singleton.getInstance();
|
||||
System.out.println(instance.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.baeldung.flyweight;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Represents a car. This class is immutable.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public class Car implements Vehicle {
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private final static Logger LOG = LoggerFactory.getLogger(Car.class);
|
||||
|
||||
/**
|
||||
* The car's engine.
|
||||
*/
|
||||
private Engine engine;
|
||||
|
||||
/**
|
||||
* The car's color.
|
||||
*/
|
||||
private Color color;
|
||||
|
||||
/**
|
||||
* Instantiates a new Car.
|
||||
*
|
||||
* @param engine
|
||||
* the {@link #engine}
|
||||
* @param color
|
||||
* the {@link #color}
|
||||
*/
|
||||
public Car(Engine engine, Color color) {
|
||||
this.engine = engine;
|
||||
this.color = color;
|
||||
|
||||
// Building a new car is a very expensive operation!
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Error while creating a new car", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.baeldung.flyweight.Vehicle#start()
|
||||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
LOG.info("Car is starting!");
|
||||
engine.start();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.baeldung.flyweight.Vehicle#stop()
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
LOG.info("Car is stopping!");
|
||||
engine.stop();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.baeldung.flyweight.Vehicle#getColor()
|
||||
*/
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.flyweight;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Engine for a vehicle.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public class Engine {
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private final static Logger LOG = LoggerFactory.getLogger(Engine.class);
|
||||
|
||||
/**
|
||||
* Starts the engine.
|
||||
*/
|
||||
public void start() {
|
||||
LOG.info("Engine is starting!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the engine.
|
||||
*/
|
||||
public void stop() {
|
||||
LOG.info("Engine is stopping!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.flyweight;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* Interface for a vehicle.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public interface Vehicle {
|
||||
|
||||
/**
|
||||
* Starts the vehicle.
|
||||
*/
|
||||
public void start();
|
||||
|
||||
/**
|
||||
* Stops the vehicle.
|
||||
*/
|
||||
public void stop();
|
||||
|
||||
/**
|
||||
* Gets the color of the vehicle.
|
||||
*
|
||||
* @return the color of the vehicle
|
||||
*/
|
||||
public Color getColor();
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.baeldung.flyweight;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Factory which implements the Flyweight pattern to return an existing vehicle
|
||||
* if present or a new one otherwise.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public class VehicleFactory {
|
||||
|
||||
/**
|
||||
* Stores the already created vehicles.
|
||||
*/
|
||||
private static Map<Color, Vehicle> vehiclesCache = new HashMap<Color, Vehicle>();
|
||||
|
||||
/**
|
||||
* Private constructor to prevent this class instantiation.
|
||||
*/
|
||||
private VehicleFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vehicle of the same color passed as argument. If that vehicle
|
||||
* was already created by this factory, that vehicle is returned, otherwise
|
||||
* a new one is created and returned.
|
||||
*
|
||||
* @param color
|
||||
* the color of the vehicle to return
|
||||
* @return a vehicle of the specified color
|
||||
*/
|
||||
public static Vehicle createVehicle(Color color) {
|
||||
// Looks for the requested vehicle into the cache.
|
||||
// If the vehicle doesn't exist, a new one is created.
|
||||
Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> {
|
||||
// Creates the new car.
|
||||
Engine newEngine = new Engine();
|
||||
return new Car(newEngine, newColor);
|
||||
});
|
||||
return newVehicle;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.freebuilder;
|
||||
|
||||
import org.inferred.freebuilder.FreeBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@FreeBuilder
|
||||
public interface Address {
|
||||
|
||||
Optional<String> getAddressLine1();
|
||||
|
||||
Optional<String> getAddressLine2();
|
||||
|
||||
Optional<String> getAddressLine3();
|
||||
|
||||
String getCity();
|
||||
|
||||
Optional<String> getState();
|
||||
|
||||
Optional<Long> getPinCode();
|
||||
|
||||
class Builder extends Address_Builder {
|
||||
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.baeldung.freebuilder;
|
||||
|
||||
import org.inferred.freebuilder.FreeBuilder;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@FreeBuilder
|
||||
public interface Employee {
|
||||
|
||||
String getName();
|
||||
|
||||
int getAge();
|
||||
|
||||
String getDepartment();
|
||||
|
||||
String getRole();
|
||||
|
||||
String getSupervisorName();
|
||||
|
||||
String getDesignation();
|
||||
|
||||
String getEmail();
|
||||
|
||||
long getPhoneNumber();
|
||||
|
||||
Optional<Boolean> getPermanent();
|
||||
|
||||
Optional<String> getDateOfJoining();
|
||||
|
||||
@Nullable
|
||||
String getCurrentProject();
|
||||
|
||||
Address getAddress();
|
||||
|
||||
List<Long> getAccessTokens();
|
||||
|
||||
Map<String, Long> getAssetsSerialIdMapping();
|
||||
|
||||
Optional<Double> getSalaryInUSD();
|
||||
|
||||
|
||||
class Builder extends Employee_Builder {
|
||||
|
||||
public Builder() {
|
||||
// setting default value for department
|
||||
setDepartment("Builder Pattern");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setEmail(String email) {
|
||||
if (checkValidEmail(email))
|
||||
return super.setEmail(email);
|
||||
else
|
||||
throw new IllegalArgumentException("Invalid email");
|
||||
|
||||
}
|
||||
|
||||
private boolean checkValidEmail(String email) {
|
||||
return email.contains("@");
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.freebuilder.builder;
|
||||
|
||||
public class Employee {
|
||||
|
||||
private final String name;
|
||||
private final int age;
|
||||
private final String department;
|
||||
|
||||
private Employee(String name, int age, String department) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String name;
|
||||
private int age;
|
||||
private String department;
|
||||
|
||||
public Builder setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAge(int age) {
|
||||
this.age = age;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDepartment(String department) {
|
||||
this.department = department;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Employee build() {
|
||||
return new Employee(name, age, department);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.singleton;
|
||||
|
||||
public class ClassSingleton {
|
||||
|
||||
private static ClassSingleton INSTANCE;
|
||||
private String info = "Initial class info";
|
||||
|
||||
private ClassSingleton(){
|
||||
}
|
||||
|
||||
public static ClassSingleton getInstance(){
|
||||
if(INSTANCE == null){
|
||||
INSTANCE = new ClassSingleton();
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// getters and setters
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.singleton;
|
||||
|
||||
public enum EnumSingleton {
|
||||
|
||||
INSTANCE("Initial enum info"); //Name of the single instance
|
||||
|
||||
private String info;
|
||||
|
||||
private EnumSingleton(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public EnumSingleton getInstance(){
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
//getters and setters
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.singleton;
|
||||
|
||||
public class Sandbox {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
//Class singleton
|
||||
|
||||
ClassSingleton classSingleton1 = ClassSingleton.getInstance();
|
||||
//OurSingleton object1 = new OurSingleton(); // The constructor OurSingleton() is not visible
|
||||
|
||||
System.out.println(classSingleton1.getInfo()); //Initial class info
|
||||
|
||||
ClassSingleton classSingleton2 = ClassSingleton.getInstance();
|
||||
classSingleton2.setInfo("New class info");
|
||||
|
||||
System.out.println(classSingleton1.getInfo()); //New class info
|
||||
System.out.println(classSingleton2.getInfo()); //New class info
|
||||
|
||||
//Enum singleton
|
||||
|
||||
EnumSingleton enumSingleton1 = EnumSingleton.INSTANCE.getInstance();
|
||||
|
||||
System.out.println(enumSingleton1.getInfo()); //Initial enum info
|
||||
|
||||
EnumSingleton enumSingleton2 = EnumSingleton.INSTANCE.getInstance();
|
||||
enumSingleton2.setInfo("New enum info");
|
||||
|
||||
System.out.println(enumSingleton1.getInfo()); //New enum info
|
||||
System.out.println(enumSingleton2.getInfo()); //New enum info
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
/**
|
||||
* Double-checked locking design pattern applied to a singleton.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class DclSingleton {
|
||||
|
||||
/**
|
||||
* Current instance of the singleton.
|
||||
*/
|
||||
private static volatile DclSingleton instance;
|
||||
|
||||
/**
|
||||
* Private constructor to avoid instantiation.
|
||||
*/
|
||||
private DclSingleton() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current instance of the singleton.
|
||||
*
|
||||
* @return the current instance of the singleton
|
||||
*/
|
||||
public static DclSingleton getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (DclSingleton.class) {
|
||||
if (instance == null) {
|
||||
instance = new DclSingleton();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
/**
|
||||
* Draconian singleton. The method to get the instance is synchronized.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class DraconianSingleton {
|
||||
|
||||
/**
|
||||
* Current instance of the singleton.
|
||||
*/
|
||||
private static DraconianSingleton instance;
|
||||
|
||||
/**
|
||||
* Private constructor to avoid instantiation.
|
||||
*/
|
||||
private DraconianSingleton() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current instance of the singleton.
|
||||
*
|
||||
* @return the current instance of the singleton
|
||||
*/
|
||||
public static synchronized DraconianSingleton getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DraconianSingleton();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
/**
|
||||
* Singleton with early initialization. Inlines the singleton instance
|
||||
* initialization.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class EarlyInitSingleton {
|
||||
|
||||
/**
|
||||
* Current instance of the singleton.
|
||||
*/
|
||||
private static final EarlyInitSingleton INSTANCE = new EarlyInitSingleton();
|
||||
|
||||
/**
|
||||
* Private constructor to avoid instantiation.
|
||||
*/
|
||||
private EarlyInitSingleton() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current instance of the singleton.
|
||||
*
|
||||
* @return the current instance of the singleton
|
||||
*/
|
||||
public static EarlyInitSingleton getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
/**
|
||||
* Enum singleton pattern. Uses an enum to hold a reference to the singleton
|
||||
* instance.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public enum EnumSingleton {
|
||||
|
||||
/**
|
||||
* Current instance of the singleton.
|
||||
*/
|
||||
INSTANCE;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
/**
|
||||
* Initialization on demand singleton pattern. Uses a nested static class to
|
||||
* hold a reference to the singleton instance.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class InitOnDemandSingleton {
|
||||
|
||||
/**
|
||||
* Holder for a singleton instance.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
private static class InstanceHolder {
|
||||
|
||||
/**
|
||||
* Current instance of the singleton.
|
||||
*/
|
||||
private static final InitOnDemandSingleton INSTANCE = new InitOnDemandSingleton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor to avoid instantiation.
|
||||
*/
|
||||
private InitOnDemandSingleton() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current instance of the singleton.
|
||||
*
|
||||
* @return the current instance of the singleton
|
||||
*/
|
||||
public static InitOnDemandSingleton getInstance() {
|
||||
return InstanceHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.constructorsstaticfactorymethods;
|
||||
|
||||
import com.baeldung.constructorsstaticfactorymethods.entities.User;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UserUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenUserClass_whenCalledcreateWithDefaultCountry_thenCorrect() {
|
||||
assertThat(User.createWithDefaultCountry("John", "john@domain.com")).isInstanceOf(User.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetName_thenCorrect() {
|
||||
User user = User.createWithDefaultCountry("John", "john@domain.com");
|
||||
assertThat(user.getName()).isEqualTo("John");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetEmail_thenCorrect() {
|
||||
User user = User.createWithDefaultCountry("John", "john@domain.com");
|
||||
assertThat(user.getEmail()).isEqualTo("john@domain.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetCountry_thenCorrect() {
|
||||
User user = User.createWithDefaultCountry("John", "john@domain.com");
|
||||
assertThat(user.getCountry()).isEqualTo("Argentina");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserInstanceCreatedWithcreateWithInstantiationTime_whenCalledcreateWithInstantiationTime_thenCorrect() {
|
||||
assertThat(User.createWithLoggedInstantiationTime("John", "john@domain.com", "Argentina")).isInstanceOf(User.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserInstanceCreatedWithgetSingletonIntance_whenCalledgetSingletonInstance_thenCorrect() {
|
||||
User user1 = User.getSingletonInstance("John", "john@domain.com", "Argentina");
|
||||
User user2 = User.getSingletonInstance("John", "john@domain.com", "Argentina");
|
||||
assertThat(user1).isEqualTo(user2);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.creational.abstractfactory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class AbstractPatternIntegrationTest {
|
||||
@Test
|
||||
public void givenAbstractFactory_whenGettingObjects_thenSuccessful() {
|
||||
AbstractFactory abstractFactory;
|
||||
|
||||
//creating a brown toy dog
|
||||
abstractFactory = FactoryProvider.getFactory("Toy");
|
||||
Animal toy = (Animal) abstractFactory.create("Dog");
|
||||
|
||||
abstractFactory = FactoryProvider.getFactory("Color");
|
||||
Color color =(Color) abstractFactory.create("Brown");
|
||||
|
||||
String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound();
|
||||
assertEquals("A Dog with brown color Barks", result);
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.creational.builder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class BuilderPatternIntegrationTest {
|
||||
@Test
|
||||
public void whenCreatingObjectThroughBuilder_thenObjectValid() {
|
||||
BankAccount newAccount = new BankAccount
|
||||
.BankAccountBuilder("Jon", "22738022275")
|
||||
.withEmail("jon@example.com")
|
||||
.wantNewsletter(true)
|
||||
.build();
|
||||
|
||||
assertEquals(newAccount.getName(), "Jon");
|
||||
assertEquals(newAccount.getAccountNumber(), "22738022275");
|
||||
assertEquals(newAccount.getEmail(), "jon@example.com");
|
||||
assertEquals(newAccount.isNewsletter(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSkippingOptionalParameters_thenObjectValid() {
|
||||
BankAccount newAccount = new BankAccount
|
||||
.BankAccountBuilder("Jon", "22738022275")
|
||||
.build();
|
||||
|
||||
assertEquals(newAccount.getName(), "Jon");
|
||||
assertEquals(newAccount.getAccountNumber(), "22738022275");
|
||||
assertEquals(newAccount.getEmail(), null);
|
||||
assertEquals(newAccount.isNewsletter(), false);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.creational.factory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class FactoryIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenUsingFactoryForSquare_thenCorrectObjectReturned() {
|
||||
Polygon p;
|
||||
PolygonFactory factory = new PolygonFactory();
|
||||
|
||||
//get the shape which has 4 sides
|
||||
p = factory.getPolygon(4);
|
||||
String result = "The shape with 4 sides is a " + p.getType();
|
||||
|
||||
assertEquals("The shape with 4 sides is a Square", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingFactoryForOctagon_thenCorrectObjectReturned() {
|
||||
Polygon p;
|
||||
PolygonFactory factory = new PolygonFactory();
|
||||
|
||||
//get the shape which has 4 sides
|
||||
p = factory.getPolygon(8);
|
||||
String result = "The shape with 8 sides is a " + p.getType();
|
||||
|
||||
assertEquals("The shape with 8 sides is a Octagon", result);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.creational.singleton;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class SingletonIntegrationTest {
|
||||
|
||||
@Test
|
||||
/**
|
||||
* Although there is absolutely no way to determine whether
|
||||
* a class is Singleton, in this test case, we will just
|
||||
* check for two objects if they point to same instance or
|
||||
* not. We will also check for their hashcode.
|
||||
*/
|
||||
public void whenGettingMultipleObjects_thenAllPointToSame() {
|
||||
//first object
|
||||
Singleton obj1 = Singleton.getInstance();
|
||||
|
||||
//Second object
|
||||
Singleton obj2 = Singleton.getInstance();
|
||||
|
||||
assertTrue(obj1 == obj2);
|
||||
assertEquals(obj1.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.flyweight;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit test for {@link VehicleFactory}.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public class FlyweightUnitTest {
|
||||
|
||||
/**
|
||||
* Checks that when the {@link VehicleFactory} is asked to provide two
|
||||
* vehicles of different colors, the objects returned are different.
|
||||
*/
|
||||
@Test
|
||||
public void givenDifferentFlyweightObjects_whenEquals_thenFalse() {
|
||||
Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK);
|
||||
Vehicle blueVehicle = VehicleFactory.createVehicle(Color.BLUE);
|
||||
|
||||
Assert.assertNotNull("Object returned by the factory is null!", blackVehicle);
|
||||
Assert.assertNotNull("Object returned by the factory is null!", blueVehicle);
|
||||
Assert.assertNotEquals("Objects returned by the factory are equals!", blackVehicle, blueVehicle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that when the {@link VehicleFactory} is asked to provide two
|
||||
* vehicles of the same colors, the same object is returned twice.
|
||||
*/
|
||||
@Test
|
||||
public void givenSameFlyweightObjects_whenEquals_thenTrue() {
|
||||
Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK);
|
||||
Vehicle anotherBlackVehicle = VehicleFactory.createVehicle(Color.BLACK);
|
||||
|
||||
Assert.assertNotNull("Object returned by the factory is null!", blackVehicle);
|
||||
Assert.assertNotNull("Object returned by the factory is null!", anotherBlackVehicle);
|
||||
Assert.assertEquals("Objects returned by the factory are not equals!", blackVehicle, anotherBlackVehicle);
|
||||
}
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
package com.baeldung.freebuilder;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EmployeeBuilderUnitTest {
|
||||
|
||||
private static final int PIN_CODE = 223344;
|
||||
public static final String CITY_NAME = "New York";
|
||||
public static final int INPUT_SALARY_EUROS = 10000;
|
||||
public static final double EUROS_TO_USD_RATIO = 0.6;
|
||||
|
||||
@Test
|
||||
public void whenBuildEmployeeWithAddress_thenReturnEmployeeWithValidAddress() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setPermanent(true)
|
||||
.setRole("developer")
|
||||
.setAddress(address)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getAddress().getCity().equalsIgnoreCase(CITY_NAME));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMapSalary_thenReturnEmployeeWithSalaryInUSD() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).setPinCode(PIN_CODE).build();
|
||||
|
||||
long salaryInEuros = INPUT_SALARY_EUROS;
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder
|
||||
.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setPermanent(true)
|
||||
.setRole("developer")
|
||||
.setAddress(address)
|
||||
.mapSalaryInUSD(sal -> salaryInEuros * EUROS_TO_USD_RATIO)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getAddress().getPinCode().get() == PIN_CODE);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenOptionalFields_thenReturnEmployeeWithEmptyValues() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setPermanent(true)
|
||||
.setRole("developer")
|
||||
.setAddress(address)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getPermanent().isPresent());
|
||||
assertTrue(employee.getPermanent().get());
|
||||
assertFalse(employee.getDateOfJoining().isPresent());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNullableFields_thenReturnEmployeeWithNullValueForField() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setNullablePermanent(null)
|
||||
.setDateOfJoining(Optional.empty())
|
||||
.setRole("developer")
|
||||
.setAddress(address)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertNull(employee.getCurrentProject());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCollectionFields_thenReturnEmployeeWithValues() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setNullablePermanent(null)
|
||||
.setDateOfJoining(Optional.empty())
|
||||
.setRole("developer")
|
||||
.addAccessTokens(1221819L)
|
||||
.addAccessTokens(1223441L, 134567L)
|
||||
.setAddress(address)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getAccessTokens().size() == 3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMapFields_thenReturnEmployeeWithValues() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setNullablePermanent(null)
|
||||
.setDateOfJoining(Optional.empty())
|
||||
.setRole("developer")
|
||||
.addAccessTokens(1221819L)
|
||||
.addAccessTokens(1223441L, 134567L)
|
||||
.putAssetsSerialIdMapping("Laptop", 12345L)
|
||||
.setAddress(address)
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getAssetsSerialIdMapping().size() == 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNestedBuilderTypes_thenReturnEmployeeWithValues() {
|
||||
|
||||
// when
|
||||
Address.Builder addressBuilder = new Address.Builder();
|
||||
Address address = addressBuilder.setCity(CITY_NAME).build();
|
||||
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setDesignation("author")
|
||||
.setEmail("abc@xyz.com")
|
||||
.setSupervisorName("Admin")
|
||||
.setPhoneNumber(4445566)
|
||||
.setNullablePermanent(null)
|
||||
.setDateOfJoining(Optional.empty())
|
||||
.setRole("developer")
|
||||
.addAccessTokens(1221819L)
|
||||
.addAccessTokens(1223441L, 134567L)
|
||||
.putAssetsSerialIdMapping("Laptop", 12345L)
|
||||
.setAddress(address)
|
||||
.mutateAddress(a -> a.setPinCode(112200))
|
||||
.build();
|
||||
|
||||
// then
|
||||
assertTrue(employee.getAssetsSerialIdMapping().size() == 1);
|
||||
|
||||
}
|
||||
|
||||
@Test()
|
||||
public void whenPartialEmployeeWithValidEmail_thenReturnEmployeeWithEmail() {
|
||||
|
||||
// when
|
||||
Employee.Builder builder = new Employee.Builder();
|
||||
|
||||
Employee employee = builder.setName("baeldung")
|
||||
.setAge(10)
|
||||
.setEmail("abc@xyz.com")
|
||||
.buildPartial();
|
||||
|
||||
assertNotNull(employee.getEmail());
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.freebuilder.builder;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
class EmployeeBuilderUnitTest {
|
||||
|
||||
public static final String NAME = "baeldung";
|
||||
|
||||
@Test
|
||||
public void whenBuildEmployee_thenReturnValidEmployee() {
|
||||
|
||||
// when
|
||||
Employee.Builder emplBuilder = new Employee.Builder();
|
||||
|
||||
Employee employee = emplBuilder
|
||||
.setName(NAME)
|
||||
.setAge(12)
|
||||
.setDepartment("Builder Pattern")
|
||||
.build();
|
||||
|
||||
//then
|
||||
Assertions.assertTrue(employee.getName().equalsIgnoreCase(NAME));
|
||||
}
|
||||
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
package com.baeldung.singleton.synchronization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for the singleton synchronization package with the same name.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*
|
||||
*/
|
||||
public class SingletonSynchronizationIntegrationTest {
|
||||
|
||||
/**
|
||||
* Size of the thread pools used.
|
||||
*/
|
||||
private static final int POOL_SIZE = 1_000;
|
||||
|
||||
/**
|
||||
* Number of tasks to submit.
|
||||
*/
|
||||
private static final int TASKS_TO_SUBMIT = 1_000_000;
|
||||
|
||||
/**
|
||||
* Tests the thread-safety of {@link DraconianSingleton}.
|
||||
*/
|
||||
@Test
|
||||
public void givenDraconianSingleton_whenMultithreadInstancesEquals_thenTrue() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
|
||||
Set<DraconianSingleton> resultSet = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// Submits the instantiation tasks.
|
||||
for (int i = 0; i < TASKS_TO_SUBMIT; i++) {
|
||||
executor.submit(() -> resultSet.add(DraconianSingleton.getInstance()));
|
||||
}
|
||||
|
||||
// Since the instance of the object we inserted into the set is always
|
||||
// the same, the size should be one.
|
||||
Assert.assertEquals(1, resultSet.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the thread-safety of {@link DclSingleton}.
|
||||
*/
|
||||
@Test
|
||||
public void givenDclSingleton_whenMultithreadInstancesEquals_thenTrue() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
|
||||
Set<DclSingleton> resultSet = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// Submits the instantiation tasks.
|
||||
for (int i = 0; i < TASKS_TO_SUBMIT; i++) {
|
||||
executor.submit(() -> resultSet.add(DclSingleton.getInstance()));
|
||||
}
|
||||
|
||||
// Since the instance of the object we inserted into the set is always
|
||||
// the same, the size should be one.
|
||||
Assert.assertEquals(1, resultSet.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the thread-safety of {@link EarlyInitSingleton}.
|
||||
*/
|
||||
@Test
|
||||
public void givenEarlyInitSingleton_whenMultithreadInstancesEquals_thenTrue() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
|
||||
Set<EarlyInitSingleton> resultSet = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// Submits the instantiation tasks.
|
||||
for (int i = 0; i < TASKS_TO_SUBMIT; i++) {
|
||||
executor.submit(() -> resultSet.add(EarlyInitSingleton.getInstance()));
|
||||
}
|
||||
|
||||
// Since the instance of the object we inserted into the set is always
|
||||
// the same, the size should be one.
|
||||
Assert.assertEquals(1, resultSet.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the thread-safety of {@link InitOnDemandSingleton}.
|
||||
*/
|
||||
@Test
|
||||
public void givenInitOnDemandSingleton_whenMultithreadInstancesEquals_thenTrue() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
|
||||
Set<InitOnDemandSingleton> resultSet = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// Submits the instantiation tasks.
|
||||
for (int i = 0; i < TASKS_TO_SUBMIT; i++) {
|
||||
executor.submit(() -> resultSet.add(InitOnDemandSingleton.getInstance()));
|
||||
}
|
||||
|
||||
// Since the instance of the object we inserted into the set is always
|
||||
// the same, the size should be one.
|
||||
Assert.assertEquals(1, resultSet.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the thread-safety of {@link EnumSingleton}.
|
||||
*/
|
||||
@Test
|
||||
public void givenEnumSingleton_whenMultithreadInstancesEquals_thenTrue() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
|
||||
Set<EnumSingleton> resultSet = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// Submits the instantiation tasks.
|
||||
for (int i = 0; i < TASKS_TO_SUBMIT; i++) {
|
||||
executor.submit(() -> resultSet.add(EnumSingleton.INSTANCE));
|
||||
}
|
||||
|
||||
// Since the instance of the object we inserted into the set is always
|
||||
// the same, the size should be one.
|
||||
Assert.assertEquals(1, resultSet.size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user