Bael 1496 flyweight (#3598)
* Added flyweight pattern example. * Refactored VehicleFactory to use computeIfAbsent method.
This commit is contained in:
parent
0094a87f9a
commit
9371794370
|
@ -0,0 +1,85 @@
|
||||||
|
package com.baeldung.designpatterns.flyweight;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a car. This class is immutable.
|
||||||
|
*
|
||||||
|
* @author Donato Rimenti
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
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.designpatterns.flyweight.Vehicle#start()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
LOG.info("Car is starting!");
|
||||||
|
engine.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.baeldung.designpatterns.flyweight.Vehicle#stop()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
LOG.info("Car is stopping!");
|
||||||
|
engine.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.baeldung.designpatterns.flyweight.Vehicle#getColor()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Color getColor() {
|
||||||
|
return this.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.designpatterns.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.designpatterns.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();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.baeldung.designpatterns.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.designpatterns.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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue