Bael 1496 flyweight (#3598)

* Added flyweight pattern example.

* Refactored VehicleFactory to use computeIfAbsent method.
This commit is contained in:
Donato Rimenti 2018-02-24 08:21:36 +01:00 committed by Grzegorz Piwowarek
parent 0094a87f9a
commit 9371794370
5 changed files with 232 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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!");
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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);
}
}