JetBrains Academy: Encapsulating object creation - Kamil-Jankowski/Learning-JAVA GitHub Wiki
JetBrains Academy: Encapsulating object creation
Clock factory:
There is a hierarchy of clocks with the base interface Clock
and the class ClockFactory
to produces instances.
Implement the method produce
of the factory. It should return a clock according to the specified type string:
- "SAND" -
SandClock
; - "DIGITAL" -
DigitalClock
; - "MECH" -
MechanicalClock
.
The single constructor of the factory takes the boolean parameter produceToyClock
. It determines what the factory does when an unsuitable type of clock is passed. If it is true
, the factory should produce an instance of ToyClock
, otherwise, return null
.
class ClockFactory {
Locale localePl = new Locale.Builder().setLanguage("pl").setRegion("PL").build();
private boolean produceToyClock;
public ClockFactory(boolean produceToyClock) {
this.produceToyClock = produceToyClock;
}
/**
* It produces a clock according to a specified type: SAND, DIGITAL or MECH.
* If some other type is passed, the method produces ToyClock.
*/
public Clock produce(String type) {
type = type.toUpperCase(localePl);
switch(type){
case "SAND":
return new SandClock();
case "DIGITAL":
return new DigitalClock();
case "MECH":
return new MechanicalClock();
default:
return produceToyClock ? new ToyClock() : null;
}
}
}
Motor static factory:
In the very heart of suburbia, there stood a motor factory; in the very heart of that factory worked a programmer. Implement the static method make
of the MotorStaticFactory
that produces motors of different types. The method takes three parameters: the type
of a motor as a character, model
as a string, and power
as a long number. It should return a new motor according to the type
with initialized fields.
Here is the correspondence between the passed type and the class of the motor: 'P'
for pneumatic, 'H'
for hydraulic, 'E'
for electric and 'W'
for warp. Ignore the upper/lower case when creating motors, i.e. 'p'
must work as well as 'P'
. If an invalid character is given, the method should return null
.
class MotorStaticFactory {
/**
* It returns an initialized motor according to the specified type by the first character:
* 'P' or 'p' - pneumatic, 'H' or 'h' - hydraulic, 'E' or 'e' - electric, 'W' or 'w' - warp.
*/
public static Motor make(char type, String model, long power) {
type = Character.toUpperCase(type);
switch(type) {
case 'P':
return new PneumaticMotor(model, power);
case 'H':
return new HydraulicMotor(model, power);
case 'E':
return new ElectricMotor(model, power);
case 'W':
return new WarpDrive(model, power);
default:
return null;
}
}
}
Static factory methods for Time:
The normal way to create an instance of a class is to use a public constructor of the class. But there is another technique. A class can provide a public static factory method that returns an instance of the class. An advantage of static factory methods is that they have names that make the code easier to read.
In this problem, you have the class Time
containing three fields: hour
, minute
and second
. Implement the following static factory methods of this class:
noon()
returns an instance initialized with 12 hours, 0 minutes, and 0 seconds.midnight()
returns an instance initialized with 0 hours, 0 minutes, and 0 seconds.of(int hour, int minute, int second)
returns an instance initialized with passed hour, minute and second if the passed arguments are correct (hour: 0-23, minute: 0-59, seconds: 0-59), otherwise,null
.ofSeconds(long seconds)
returns an instance initialized with seconds passed since midnight; as an example, the invocationTime.ofSeconds(500000)
must create an instance with 18 hours, 53 minutes and 20 seconds (days are skipped);
As you see, the methods are more readable than the same constructors. If you want to create an instance of Time representing noon, you can write:
Time noon = Time.noon();
Note:
- do not change fields of the class
Time
; - in a real application, it may be better to throw an exception than return
null
when arguments are incorrect.
class Time {
int hour;
int minute;
int second;
public static Time noon() {
Time time = new Time();
time.hour = 12;
time.minute = 0;
time.second = 0;
return time;
}
public static Time midnight() {
Time time = new Time();
time.hour = 0;
time.minute = 0;
time.second = 0;
return time;
}
public static Time of(int hour, int minute, int second) {
if(hour >= 0 && hour < 24 &&
minute >= 0 && minute < 60 &&
second >= 0 && second < 60){
Time time = new Time();
time.hour = hour;
time.minute = minute;
time.second = second;
return time;
} else {
return null;
}
}
public static Time ofSeconds(long seconds) {
Time time = new Time();
time.hour = (int) (seconds / 3600 % 24);
time.minute = (int) (seconds / 60 % 60);
time.second = (int) (seconds % 60);
return time;
}
}