[Java]関数式プログラミング設計モード
55179 ワード
Design Pattern
ビルダーモード
作成者のパラメータは、
改良構造(Functional)
public static class Builder {
private int id;
private String name;
private Builder() {
}
public Builder with(Consumer<Builder> consumer) {
consumer.accept(this);
return this;
}
public Object build() {
return new Object(this);
}
}
public class BuilderExample {
public static void main(String[] args) {
Object obj = Object.builder()
.with(builder -> {
builder.id = 1;
builder.name = "functional builder";
}).build();
}
}
装飾図案
「価格設定」を実装するオブジェクトを入力し、状況に応じて適用可能な
public class Price {
private final String price
public Price(String price) {
this.price = price;
}
public String getPrice() {
return price;
}
}
// Functional Interface (메소드 하나)
public interface PriceProcessor {
Price process(Price price);
// 다음에 실행될 프로세서를 받아와서 기존 프로세서를 처리하고 next 프로세서를 처리해서 새로운 Price를 만들어줌
default PriceProcessor andThen(PriceProcessor next) {
return price -> next.process(process(price));
}
}
戦略モデル
定義済み
public interface Provider {
String getName(Object object);
}
public class Sender {
private Provider provider;
public Sender setProvider(Provider provider) {
this.provider = provider;
return this;
}
public void sendName(Object object) {
String name = Provider.getName(object);
}
}
public class ProviderImpl1 {
@Override
public String getName(Object object) {
return "imple type1 " + object.getName();
};
}
public class ProviderImpl2 {
@Override
public String getName(Object object) {
return "imple type2 " + object.getName();
};
}
戦略的選択の比較
public class MainClass {
public static void main(String[] args) {
Object obj1 = Object.builder("name1").build();
Object obj2 = Object.builder("name2").build();
Object obj3 = Object.builder("name3").build();
List<Object> objs = Arrays.asList(obj1, obj2, obj3);
Sender sender = new Sender();
Provider provider1 = new ProviderImpl1();
Provider provider2 = new ProviderImpl2();
// 전략 선택 1
sender.setProvider(provider1);
objs.stream()
.forEach(sender::sendName);
// 전략 선택 2
sender.setProvider(provider2);
objs.stream()
.forEach(sender::sendName);
// 함수형 프로그래밍 개선 (바로 바로 생성해 사용 가능)
sender.setProvider(object -> "functional " + object.getName()).stream()
.forEach(sender::sendName);
};
}
テンプレートメソッドアレイ
既存の構造
public abstract class AbstractService {
protected abstract boolean validateObject(Object object);
protected abstract void writeToDB(Object object);
public void createObject(Object object) {
if(validateObject(object)) {
writeToDB(object);
} else {
System.out.println("Cannot create");
}
}
}
public class Service extends AbstractService {
@Override
protected abstract boolean validateObject(Object object) {
return object.getName() != null && user.getFields().isPresent();
}
@Override
protected abstract void writeToDB(Object object) {
System.out.println("write " + object.getName() + " to DB");
}
}
// 내부 서비스
public class InternalService extends AbstractService {
@Override
protected abstract boolean validateObject(Object object) {
return true;
}
@Override
protected abstract void writeToDB(Object object) {
System.out.println("write " + object.getName() + " to internal DB");
}
}
public class MainClass {
public static void main(String[] args) {
Object object = Object.builder("name")
.with(builder -> {
builder.fields = "fields";
}).build();
}
Service service = new Service();
InternalService internalService = new InternalService();
service.createUser(object);
internalService.createUser(object);
}
改良構造(Functional)
public class FunctionalService extends AbstractService {
private final Predicate<Object> validateObject;
private final Consumer<Object> writeToDB;
public FunctionalService(Predicate<Object> validateObject, Consumer<Object> writeToDB) {
this.validateObject = validateObject;
this.writeToDB = writeToDB;
}
public void createObject(Object object) {
if(validateObject.test(object)) {
writeToDB.accept(object);
} else {
System.out.println("Cannot create");
}
}
}
public class MainClass {
public static void main(String[] args) {
Object object = Object.builder("name")
.with(builder -> {
builder.fields = "fields";
}).build();
}
FunctionalService fService = new FunctionalService(
object -> {
return object.getName().equal("functional");
},
object -> {
System.out.println("functional writeToDB " + object.getName());
}
)
fService.createObject(object);
}
責任チェーンモード
チェーン
定義#テイギ#
public Class OrderProcessStep {
private final Consumer<Order> processOrder;
private OrderProcessStep next;
public OrderProcessStep(Consumer<Order> processOrder) {
this.processOrder = processOrder;
}
public OrderProcessStep setNext(OrderProcessStep next) {
if (this.next == null) {
this.next = next;
} else {
this.next.setNext(next);
}
return this;
}
public void process(Order order) {
processOrder.accept(order);
Optional.ofNullable(next)
.ifPresent(nextStep -> nextStep.process(order));
}
}
各ステップの実装
public class MainClass {
public static void main(String[] args) {
OrderProcessStep initializeStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.CREATED) {
logger.info("Start processing order " + order.getId());
order.setStatus(OrderStatus.IN_PROGRESS);
}
});
OrderProcessStep setOrderAmountStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.IN_PROGRESS) {
logger.info("Setting amount of order " + order.getId());
order.setAmount(
order.getOrderLines().stream()
.map(OrderLine::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add)
);
}
}
OrderProcessStep verifyOrderStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.IN_PROGRESS) {
logger.info("Verifying order " + order.getId());
if(order.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
order.setStatus(OrderStatus.ERROR);
}
}
}
OrderProcessStep paymentStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.IN_PROGRESS) {
logger.info("payment of order " + order.getId());
order.setStatus(OrderStatus.PROCESSED);
}
}
OrderProcessStep handleErrorStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.ERROR) {
logger.info("Error in order " + order.getId());
}
}
OrderProcessStep completeOrderStep = new OrderProcessStep(order -> {
if(order.getStatus() == OrderStatus.PROCESSED) {
logger.info("finished processing order " + order.getId());
}
}
// 체이닝
OrderProcessStep chainedOrderProcessSteps = initializeStep
.setNext(setOrderAmountStep)
.setNext(verifyOrderStep)
.setNext(paymentStep)
.setNext(handleErrorStep)
.setNext(completeOrderStep);
// 체인 실행
chainedOrderProcessSteps.process(order);
}
}
Reference
この問題について([Java]関数式プログラミング設計モード), 我々は、より多くの情報をここで見つけました https://velog.io/@fortice/Java-함수형-프로그래밍-디자인-패턴テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol