import java.util.Scanner;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.util.List;
import java.util.ArrayList;
// 二項演算シミュレータ。一部だけをユーザに公開
public class BinaryOperationSimulator {
    private int x;
    private int y;
    private List<BinaryOperator> operators;
    // 計算手順。これはシミュレータが提供する。ユーザには触らせない。
    public BinaryOperationSimulator(){
        operators = new ArrayList<>();
        inputNumbers();
        showNumbers();
        registerOperators();
        List<Integer> results = calcBinaryOperation();
        System.out.println(results);
    }
    // 二項演算に必要な数を入力させる。ユーザには触らせない。
    public void inputNumbers() {
        Scanner scan = new Scanner(System.in);
        System.out.print("You can input two numbers: ");
        this.x = scan.nextInt();
        this.y = scan.nextInt();
    }
    public void showNumbers(){
        System.out.println(String.format("x=%d and y=%d was inputed.", x, y));
    }
    // 二項演算の計算を登録する。ユーザには触らせない。
    public void register(BinaryOperator op){
        operators.add(op);
    }
    // 唯一ユーザに触らせる箇所。定義した二項演算をregisterメソッドを使って登録する。
    public void registerOperators(){
        register(new Adder());
        register(new Multiplier());
    }
    // 登録された二項演算を使い計算をしていく。
    public List<Integer> calcBinaryOperation(){
        return operators.stream().map(op -> op.apply(x, y)).collect(Collectors.toList());
    }
    public static void main(String[] args){
        new BinaryOperationSimulator();
    }
}