弊社からのお知らせ

最新のトピック、気になる技術情報をつぶやきます。気になる方はチェックしてみて下さい。

【chatgpt 1問1答 23回目】Javaで関数型のデザインパターンのメジャー所を3つサンプル(悪い例と良い例)を教えて#プログラミング
Javaで使用される主要な関数型デザインパターンと、それぞれの良い例と悪い例を以下に挙げます。
これらのパターンは、関数型プログラミングの特徴を生かしたモダンな設計手法を反映しています。

1. ストラテジーパターン (Strategy Pattern)
関数型プログラミングを活用することで、異なるアルゴリズムを簡単に切り替えられるように設計。

悪い例 (従来の手法):
class PaymentProcessor {
    void processPayment(String type) {
        if ("credit".equals(type)) {
            System.out.println("credit payment");
        } else if ("paypal".equals(type)) {
            System.out.println("paypal payment");
        } else {
            throw new IllegalArgumentException(
                "Unsupport");
        }
    }
}
良い例 (関数型):
import java.util.function.Consumer;

class PaymentProcessor {
    void processPayment(Consumer paymentStrategy) {
        paymentStrategy.accept("Payment details");
    }
}

public class Main {
    public static void main(String[] args) {
        PaymentProcessor processor =
                new PaymentProcessor();
        processor.processPayment(
            details -> System.out.println(
                "credit: " + details));
        processor.processPayment(
            details -> System.out.println(
                "paypal : " + details));
    }
}

2. コマンドパターン (Command Pattern)
関数型スタイルでは、動作を直接関数として表現できる。

悪い例 (クラスベース):
interface Command {
    void execute();
}

class PrintCommand implements Command {
    public void execute() {
        System.out.println("Print document");
    }
}

class Main {
    public static void main(String[] args) {
        Command printCommand = new PrintCommand();
        printCommand.execute();
    }
}

良い例 (ラムダ式):
public class Main {
    public static void main(String[] args) {
        Runnable command
            = () -> System.out.println("Print document");
        command.run();
    }
}

3. ビルダーパターン (Builder Pattern)
関数型ではメソッドチェーンやラムダを利用して簡潔に記述。
悪い例 (冗長な実装):
class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and toString...
}

class UserBuilder {
    private String name;
    private int age;

    UserBuilder setName(String name) {
        this.name = name;
        return this;
    }

    UserBuilder setAge(int age) {
        this.age = age;
        return this;
    }

    User build() {
        return new User(name, age);
    }
}

良い例 (関数型アプローチ):
import java.util.function.Consumer;

class User {
    private String name;
    private int age;

    private User() {}

    public static User create(Consumer builder) {
        User user = new User();
        builder.accept(user);
        return user;
    }

    public void setName(String name) { this.name = name; }
    public void setAge(int age) { this.age = age; }

    @Override
    public String toString() {
        return "User{name='" + name + "', 
            age=" + age + "}";
    }
}

public class Main {
    public static void main(String[] args) {
        User user = User.create(u -> {
            u.setName("John");
            u.setAge(30);
        });
        System.out.println(user);
    }
}
2025/01/23 18:50:28