JetBrains Academy: Factory method - Kamil-Jankowski/Learning-JAVA GitHub Wiki

JetBrains Academy: Factory method

Burger store:

In this task, you'll be asked to write almost a full working code by yourself. However, you can find some tips in the correct output and in parts of the code.

Let's create the BurgerStore. We will stick to the good old classic and simply create a burger with Bun, Cutlet and Sauce.

Sample Output 1:

Making a Chinese Burger
Putting bun
Putting cutlet
Putting sauce
Done a Chinese Burger

Making a American Burger
Putting bun
Putting cutlet
Putting sauce
Done a American Burger

Making a Russian Burger
Putting bun
Putting cutlet
Putting sauce
Done a Russian Burger

Do not forget that FactoryMethod does not include details, it only knows the general creation process.

class TestDrive {
    public static void main(String[] args) throws InterruptedException {
        BurgerStore kamilsBurgers = new BurgerStore();
        kamilsBurgers.orderBurger("Chinese");
        kamilsBurgers.orderBurger("American");
        kamilsBurgers.orderBurger("Russian");
    }
}

abstract class BurgerFactory {

    abstract Burger createBurger(String type);

    Burger orderBurger(String type) throws InterruptedException {
        Burger burger = createBurger(type);
        if (burger == null) {
            System.out.println("Sorry, we are not able to create this kind of burger\n");
            return null;
        }
        System.out.println("Making a " + burger.getName());
        burger.putBun();
        burger.putCutlet();
        burger.putSauce();
        Thread.sleep(1500L);
        System.out.println("Done a " + burger.getName() + "\n");
        return burger;
    }
}

class BurgerStore extends BurgerFactory {
    @Override
    Burger createBurger(String type) {
        switch (type) {
            case "Chinese":
                return new ChineseBurger("Chinese Burger");
            case "American":
                return new AmericanBurger("American Burger");
            case "Russian":
                return new RussianBurger("Russian Burger");
            default:
                return null;
        }
    }
}

abstract class Burger {
    private String name;

    Burger(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    void putBun() {
        System.out.println("Putting bun");
    }

    void putCutlet() {
        System.out.println("Putting cutlet");
    }

    void putSauce() {
        System.out.println("Putting sauce");
    }

}

class ChineseBurger extends Burger {
    ChineseBurger(String name){
        super(name);
    }
}

class AmericanBurger extends Burger {
    AmericanBurger(String name){
        super(name);
    }
}

class RussianBurger extends Burger {
    RussianBurger(String name){
        super(name);
    }
}

Clocks:

Given classes are the Clock interface of products, specified clocks, and the factory class ClockFactory to produce instances.

Your task is to implement the factory method produce. It should return a clock according to the specified type string:

  • "Sand" — SandClock;
  • "Digital" — DigitalClock;
  • "Mech" — MechanicalClock.

Sample Input 1: Digital

Sample Output 1: ...pim...

Please, do not change the provided code of the clock classes.

class ClockFactory {
    Locale localePl = new Locale.Builder().setLanguage("pl").setRegion("PL").build();

    /* It produces concrete clocks corresponding their types : Digital, Sand or Mechanical */
    public Clock produce(String type) {
        type = type.toUpperCase(localePl);

        switch(type){
            case "DIGITAL":
                return new DigitalClock();
            case "SAND":
                return new SandClock();
            case "MECH":
                return new MechanicalClock();
            default:
                return null;
        }
    }
}

Laptop store:

The first part of the task is to imagine you are the boss of a LaptopStore. The real task though is the code: your engineer should be able to create 17'', 15'' or 13'' laptops without any concrete details.

Sample Output 1:

Making a 13 inch Laptop
Attaching keyboard
Attaching trackpad
Attaching display
Done a 13 inch Laptop

Making a 15 inch Laptop
Attaching keyboard
Attaching trackpad
Attaching display
Done a 15 inch Laptop

Making a 17 inch Laptop
Attaching keyboard
Attaching trackpad
Attaching display
Done a 17 inch Laptop
class TestDrive {
    public static void main(String[] args) throws InterruptedException {
        LaptopStore laptopStore = new LaptopStore();    // creating object of Concrete Creator of factory method

        laptopStore.orderLaptop("13 inch");
        laptopStore.orderLaptop("15 inch");
        laptopStore.orderLaptop("17 inch");
    }
}

Motors:

A lovely idea befalls you: you decide to automate the production of motors.

You have 4 types of motors: electric, hydraulic, pneumatic and warp drive.

You must implement MotorFactory and specified classes of motors.

Please, do not change the provided code of the motor classes.

Sample Input 1: E R-45 1000

Sample Output 1: Electric motor={model:R-45,power:1000}

import java.util.Scanner;

/* Product - Motor */
abstract class Motor {

    String model;
    long power;

    public Motor(String model, long power) {
        this.model = model;
        this.power = power;
    }

    @Override
    public String toString() {
        return "motor={model:" + model + ",power:" + power + "}";
    }
}

class PneumaticMotor extends Motor {
    // write your code here...
    PneumaticMotor(String model, long power){
        super(model, power);
    }
    @Override
    public String toString() {
        return "Pneumatic " + super.toString();
    }
}

class HydraulicMotor extends Motor {
    // write your code here...    
    HydraulicMotor(String model, long power){
        super(model, power);
    }
    @Override
    public String toString() {
        return "Hydraulic " + super.toString();
    }
}

class ElectricMotor extends Motor {
    // write your code here...
    ElectricMotor(String model, long power){
        super(model, power);
    }
    @Override
    public String toString() {
        return "Electric " + super.toString();
    }
}

class WarpDrive extends Motor {
    // write your code here...
    WarpDrive(String model, long power){
        super(model, power);
    }
    @Override
    public String toString() {
        return "Warp drive={model:" + model + ",power:" + power + "}";
    }
}

class MotorFactory {

    /**
     * It returns an initialized motor according to the specified type by the first chacater:
     * '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) {
        // write your code here...
        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;
        }
    }
}

public class Main {
    public static void main(String args[]) {
        final Scanner scanner = new Scanner(System.in);
        final char type = scanner.next().charAt(0);     
        final String model = scanner.next();
        final long power = scanner.nextLong();
        // write your code here...
        MotorFactory motorMaker = new MotorFactory();
        Motor motor = motorMaker.make(type, model, power);
        //
        scanner.close();
        System.out.println(motor);
    }
}

Phone store:

Now we will ask you not only to write some code in TestDrive class, but also to pay attention to how objects are created in your PhoneStore and to the polymorphic features.

Sample Output 1:

Making a Chinese Phone
Attaching camera
Attaching display
Done a Chinese Phone

Making a American Phone
Attaching camera
Attaching display
Done a American Phone

Making a Russian Phone
Attaching camera
Attaching display
Done a Russian Phone
class TestDrive {
    public static void main(String[] args) throws InterruptedException {
        // write your code here...
        PhoneStore phoneStore = new PhoneStore();

        phoneStore.orderPhone("Chinese");
        phoneStore.orderPhone("American");
        phoneStore.orderPhone("Russian");
        //
    }
}

abstract class PhoneFactory {

    abstract Phone createPhone(String type);

    Phone orderPhone(String type) throws InterruptedException {
        Phone phone = createPhone(type);
        if (phone == null) {
            System.out.println("Sorry, we are not able to create this kind of phone\n");
            return null;
        }
        System.out.println("Making a " + phone.getName());
        // write your code here...
        phone.attachCamera();
        phone.attachDisplay();
        //
        Thread.sleep(1500L);
        System.out.println("Done a " + phone.getName() + "\n");
        return phone;
    }
}

Robot:

The given classes are components of the Factory Method pattern.

Robot is the product and RobotCleaner is the concrete product.

Implement a factory method in RobotFactory methods to create RobotCleaner.

Sample Input 1: RAS012

Sample Output 1:

cleaner-robot: {
	name : RAS012
	description : Robot will clean my room and dry my socks
	power : 100
}

Please, do not change the provided code of the classes.

class RobotFactory {
    /** Factory Method **/
    public Robot getRobot(RobotType type,String name, String description,int power) {
        if(type == RobotType.ROBOT_CLEANER){
            return new RobotCleaner(name, description, power);
        }
        return null;
    }
}

Robot factory:

Let's expand our RobotFactory! We've added a new Robot type — the Guardian.

Provide the RobotGuardian class and implement a factory method in RobotFactory methods to create Robot instances.

Sample Input 1: TYU11 O13L3

Sample Output 1:

cleaner-robot: {
	name : TYU11
	description : Robot will clean my room and dry my socks
	power : 100
}
guardian-robot: {
	name : O13L3
	description : Knight will secure my daugher while she sleeping
	power : 200
}

Please, do not change the provided code of the classes.

import java.util.Scanner; 

/** Product - Robot */
abstract class Robot {

    public abstract String getName();
    public abstract String getDescription();
    public abstract int getPower();

    @Override
    public String toString() {
        return "robot: {\n\t" +
                   "name : " + getName() + "\n\t" + 
                   "description : " + getDescription() + "\n\t" + 
                    "power : " + getPower() + "\n}";
    }
}

/** Robot types */
enum RobotType {
    ROBOT_CLEANER,
    ROBOT_GUARDIAN;
}

/** Concrete Product - Robot Cleaner */
class RobotCleaner extends Robot {

    private String name;
    private String description;
    private int power;

    public RobotCleaner(String name, String description, int power) {
        this.name = name;
        this.description = description;
        this.power = power;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getDescription() {
        return this.description;
    }

    @Override
    public int getPower() {
        return this.power;
    }

    @Override
    public String toString() {
        return "cleaner-" + super.toString();
    }

}

/** Concrete Product - Robot Guardian */
class RobotGuardian extends Robot {
    
    private String name;
    private String description;
    private int power;

    public RobotGuardian(String name, String description, int power) {
        this.name = name;
        this.description = description;
        this.power = power;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getDescription() {
        return this.description;
    }

    @Override
    public int getPower() {
        return this.power;
    }

    @Override
    public String toString() {
        return "guardian-" + super.toString();
    }
}

class RobotFactory {

    /** Factory method */
    public Robot getRobot(RobotType type,String name, String description,int power) {
        switch(type){
            case ROBOT_CLEANER:
                return new RobotCleaner(name, description, power);
            case ROBOT_GUARDIAN:
                return new RobotGuardian(name, description, power);
            default:
                return null;
        }
    }
}

class RobotDemo {
    public static void main(String[] args) {

        RobotFactory robotFactory = new RobotFactory();
        Scanner scanner = new Scanner(System.in);

        String nameCleaner = scanner.nextLine();
        Robot robotCleaner = robotFactory.getRobot(RobotType.ROBOT_CLEANER,nameCleaner,"Robot will clean my room and dry my socks",100);

        String nameGuardian = scanner.nextLine();
        Robot robotGuardian = robotFactory.getRobot(RobotType.ROBOT_GUARDIAN,nameGuardian,"Knight will secure my daugher while she sleeping",200);

        System.out.println(robotCleaner);
        System.out.println(robotGuardian);

        scanner.close();
    }
}