### Question:
PIDController extends Controller { public static PIDController of(Double kp, Double ki, Double kd, Double deltaT) { return new PIDController(kp, ki, kd, deltaT, new AtomicDouble(1.0)); } PIDController(Double kp, Double ki, Double kd, Double deltaT, AtomicDouble dampener); static PIDController of(Double kp, Double ki, Double kd, Double deltaT); static PIDController of(Double kp, Double ki, Double kd); static PIDController of(Double kp, Double ki, Double kd, Double deltaT, AtomicDouble dampener); @Override Double processStep(Double error);  }### Answer:
@Test public void shouldControlCacheSizeToMaintainDesiredHitRate() { Cache cache = new Cache(); final double setPoint = 0.75; Controller controller = PIDController.of(25.0, 1.0, 0.0); double currentSize = 0.0; for (int step = 0; step <= 100; ++step) { double hitRate = cache.process(currentSize); double error = setPoint - hitRate; double controlAction = Observable.just(error).lift(controller).toBlocking().first(); currentSize += controlAction; } assertEquals(0.75, cache.process(currentSize), 0.01); assertEquals(0.75 * 250, currentSize, 5.0); }