通过SpringBoot尝试整合观察者模式、策略模式。
这里主要是个人记录,不多做解释
package com.example.springboottest.controller; import com.example.springboottest.entity.TestModelRequest; import com.example.springboottest.obeserve.SubjectBean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Collections; import java.util.List; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 12:32 AM */ @RestController public class ObserverTest { @Resource private SubjectBean subjectBean; @ResponseBody @GetMapping("/observerTest") public List<String> observerTest(@RequestBody TestModelRequest request) { switch (request.getOption()) { case "add": return subjectBean.add(request.getTestModel()); case "update": return subjectBean.update(request.getTestModel()); case "select": return subjectBean.select(request.getTestModel()); } return Collections.emptyList(); } }
package com.example.springboottest.entity; import com.example.springboottest.obeserve.TestModel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 3:26 AM */ @Data @Builder @AllArgsConstructor @NoArgsConstructor public class TestModelRequest { private String option; private List<TestModel> testModel; }
package com.example.springboottest.obeserve; import java.util.List; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/24 11:57 PM */ public class MyObserver { protected List<String> add(TestModel testModel) throws Exception { throw new Exception(this.getClass().getName() + "没有实现add"); } protected List<String> update(TestModel testModel) throws Exception { throw new Exception(this.getClass().getName() + "没有实现update"); } protected List<String> select(TestModel testModel) throws Exception{ throw new Exception(this.getClass().getName() + "没有实现select"); } }
package com.example.springboottest.obeserve; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Collections; import java.util.List; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 12:07 AM */ @Slf4j @Component public class ObserverBean1 { @Resource private Observer1 observer1; protected List<String> add(TestModel testModel) { return Collections.singletonList("ob1 - add - " + testModel.arg1); } protected List<String> update(TestModel testModel) { return Collections.singletonList("ob1 - update - " + testModel.arg1); } protected List<String> select(TestModel testModel) { return Collections.singletonList("ob1 - select - " + testModel.arg1); } @Component class Observer1 extends MyObserver implements InitializingBean { @Resource Subject subject; @Override protected List<String> add(TestModel testModel) throws Exception { return ObserverBean1.this.add(testModel); } @Override protected List<String> update(TestModel testModel) throws Exception { return ObserverBean1.this.update(testModel); } @Override protected List<String> select(TestModel testModel) throws Exception { return ObserverBean1.this.select(testModel); } @Override public void afterPropertiesSet() throws Exception { subject.attach("observer1", this); } } }
package com.example.springboottest.obeserve; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Collections; import java.util.List; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 12:08 AM */ @Slf4j @Component public class ObserverBean2 { @Resource private Observer2 observer2; protected List<String> add(TestModel testModel) { return Collections.singletonList("ob2 - add - " + testModel.arg2); } protected List<String> update(TestModel testModel) { return Collections.singletonList("ob2 - update - " + testModel.arg2); } protected List<String> select(TestModel testModel) { return Collections.singletonList("ob2 - select - " + testModel.arg2); } @Component class Observer2 extends MyObserver implements InitializingBean { @Resource Subject subject; @Override protected List<String> add(TestModel testModel) throws Exception { return ObserverBean2.this.add(testModel); } @Override protected List<String> update(TestModel testModel) throws Exception { return ObserverBean2.this.update(testModel); } @Override protected List<String> select(TestModel testModel) throws Exception { return ObserverBean2.this.select(testModel); } @Override public void afterPropertiesSet() throws Exception { subject.attach("observer2", this); } } }
package com.example.springboottest.obeserve; import lombok.SneakyThrows; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 观察者 * * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/24 11:39 PM */ @Component public final class Subject extends MyObserver implements InitializingBean { Map<String, MyObserver> observerMap; void attach(String type, MyObserver observer) { observerMap.put(type, observer); } @SneakyThrows public List<String> add(String type, TestModel testModel) { return observerMap.get(type).add(testModel); } @SneakyThrows public List<String> update(String type, TestModel testModel) { return observerMap.get(type).update(testModel); } @SneakyThrows public List<String> select(String type, TestModel testModel) { return observerMap.get(type).select(testModel); } @Override public void afterPropertiesSet() throws Exception { observerMap = new HashMap<>(); } }
package com.example.springboottest.obeserve; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 12:07 AM */ @Slf4j @Component public class SubjectBean { @Resource private Subject subject; public void attach(String type, MyObserver myObserver) { log.info("SubjectBean attach(type: {}, myObserver : {}) ", type, myObserver); subject.attach(type, myObserver); } public String insert(String arg) { log.info("insert arg : {}", arg); return "{ SubjectBean - " + arg + " }"; } public List<String> add(List<TestModel> testModelList) { return testModelList.stream() .map(item -> subject.add(item.getType(), item)) .flatMap(Collection::stream) .collect(Collectors.toList()); } public List<String> update(List<TestModel> testModelList) { return testModelList.stream() .map(item -> subject.update(item.getType(), item)) .flatMap(Collection::stream) .collect(Collectors.toList()); } public List<String> select(List<TestModel> testModelList) { return testModelList.stream() .map(item -> subject.select(item.getType(), item)) .flatMap(Collection::stream) .collect(Collectors.toList()); } }
package com.example.springboottest.obeserve; import lombok.AllArgsConstructor; import lombok.Data; /** * @author : Ashiamd email: ashiamd@foxmail.com * @date : 2021/10/25 2:45 AM */ @Data @AllArgsConstructor public class TestModel { String type; String arg1; String arg2; String arg3; }
package com.example.springboottest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootTestApplication { public static void main(String[] args) { SpringApplication.run(SpringBootTestApplication.class, args); } }
curl --location --request GET 'http://localhost:8080/observerTest?args=hehe' \ --header 'User-Agent: apifox/1.0.0 (https://www.apifox.cn)' \ --header 'Content-Type: application/json' \ --data-raw '{ "option": "update", "testModel": [ { "type": "observer1", "arg2": "consequat", "arg1": "ullamco do adipisicing", "arg3": "Ut Excepteur" }, { "type": "observer2", "arg2": "eu ullamco", "arg1": "culpa cillum consequat nostrud", "arg3": "nisi officia ad" }, { "type": "observer1", "arg2": "commodo ad in do", "arg1": "Excepteur laboris nulla", "arg3": "ipsum culpa commodo mollit id" }, { "type": "observer1", "arg2": "Ut laboris", "arg1": "exercitation aute", "arg3": "dolor in consequat" } ] }'
[ "ob1 - update - ullamco do adipisicing", "ob2 - update - eu ullamco", "ob1 - update - Excepteur laboris nulla", "ob1 - update - exercitation aute" ]