- 观察者模式
关键词
Subject-Observer
Publisher-Subscriber
Producer-Consumer
EventEmitter-EventListener
Dispatcher-Listener
同步阻塞(一般默认),异步非阻塞,进程内,跨进程
如果要实现异步非阻塞就让notifyObserver在线程里面执行
public class Message {
private String msg;
public Message(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
}
public interface Observer {
void onResult(Message message);
}
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(Message message);
}
public class ConcreteSubject implements Subject{
private List observers = new ArrayList<>();
public void registerObserver(Observer observer){
observers.add(observer);
}
public void removeObserver(Observer observer){
observers.remove(observer);
}
public void notifyObservers(Message message){
for (Observer observer: observers) {
observer.onResult(message);
}
}
}
public class ConcernObserver1 implements Observer {
@Override
public void onResult(Message message) {
System.out.println("i am ConcernObserver1 "+message.getMsg());
}
}
public class ConcernObserver2 implements Observer {
@Override
public void onResult(Message message) {
System.out.println("i am ConcernObserver2 "+message.getMsg());
}
}
public static void main(String[] args){
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.registerObserver(new ConcernObserver1());
concreteSubject.registerObserver(new ConcernObserver2());
concreteSubject.notifyObservers(new Message("haha"));
}
手动实现一个EventBus
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Bean
public @interface Subscriber {
}
public class ObserverAction {
private Object target;
private Method method;
public ObserverAction(Object target, Method method) {
this.target = target;
this.method = method;
}
public void executed(Object event){
try {
method.invoke(target,event);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
public class ObserverRegistry {
//CopyOnWriteArraySet 写的时候,有个备份 不影响读; 多线程加锁限制
private ConcurrentMap, CopyOnWriteArraySet> registry = new ConcurrentHashMap<>();
public void register(Object observer){
Map, Collection> observerActions = findAllObserverAction(observer);
for(Map.Entry,Collection> entry : observerActions.entrySet()){
Class> eventType = entry.getKey();
Collection eventActions = entry.getValue();
CopyOnWriteArraySet registerEventActions = registry.get(eventType);
if (registerEventActions == null){
registry.putIfAbsent(eventType,new CopyOnWriteArraySet<>());
registerEventActions = registry.get(eventType);
}
registerEventActions.addAll(eventActions);
}
}
public List getMatchedObserverActions(Object event){
List matchedActionList = new ArrayList<>();
Class> postedEventType = event.getClass();
for (Map.Entry, CopyOnWriteArraySet> entry : registry.entrySet()){
Class> eventType = entry.getKey();
CopyOnWriteArraySet eventActions = entry.getValue();
if (postedEventType.isAssignableFrom(eventType)){
matchedActionList.addAll(eventActions);
}
}
return matchedActionList;
}
private Map, Collection> findAllObserverAction(Object observer){
Map,Collection> observerActions = new HashMap<>();
Class> clazz = observer.getClass();
for (Method method : getAnnotatedMethods(clazz)){
Class>[] parameterTypes = method.getParameterTypes();
Class> eventType = parameterTypes[0];
if (!observerActions.containsKey(eventType)){
observerActions.put(eventType,new ArrayList<>());
}
observerActions.get(eventType).add(new ObserverAction(observer,method));
}
return observerActions;
}
private List getAnnotatedMethods(Class> clazz){
List annotatedMethod = new ArrayList<>();
for (Method method : clazz.getDeclaredMethods()){
if (method.isAnnotationPresent(Subscriber.class)){
Class>[] parameterTypes = method.getParameterTypes();
Preconditions.checkArgument(parameterTypes.length == 1,"Method %s has @Subscribe annotation but has %s parameters." + "Subscriber methods must have exactly 1 parameter.",
method, parameterTypes.length);
annotatedMethod.add(method);
}
}
return annotatedMethod;
}
}
public class EventBus {
private ObserverRegistry observerRegistry = new ObserverRegistry();
private Executor executor;
public EventBus() {
this(MoreExecutors.directExecutor());
}
public EventBus(Executor executor) {
this.executor = executor;
}
public void register(Object object){
observerRegistry.register(object);
}
public void post(Object event){
List matchedObserverActions = observerRegistry.getMatchedObserverActions(event);
for (ObserverAction observerAction: matchedObserverActions) {
executor.execute(new Runnable() {
@Override
public void run() {
observerAction.executed(event);
}
});
}
}
}
- 模板模式
- 定义:定义了方法的骨架,将某些步骤延迟到子类实现
- 作用:复用和扩展
- 模板和Callback:模板是继承,Callback是组合
public abstract class BaseTemplate {
final void doTask(){
before();
System.out.println("BaseTemplate Task");
after();
}
protected abstract void before();
protected abstract void after();
}
public class ConcernTemplate extends BaseTemplate {
@Override
protected void before() {
System.out.println("i am ConcernTemplate before");
}
@Override
protected void after() {
System.out.println("i am ConcernTemplate after");
}
}
public interface ILoginService {
void login(String userName,String pwd);
}
public class UserService {
private ILoginService loginService;
public void addLoginService(ILoginService loginService){
this.loginService = loginService;
}
public void login(String userName,String pwd){
if (loginService != null){
loginService.login(userName,pwd);
}else {
throw new ExceptionInInitializerError("should call addLoginService before");
}
}
}
public static void main(String[] args){
BaseTemplate template = new ConcernTemplate();
template.doTask();
UserService userService = new UserService();
userService.addLoginService(new ILoginService() {
@Override
public void login(String userName, String pwd) {
if ("tml".equals(userName) & "123".equals(pwd)){
System.out.println("login Success");
}else {
System.out.println("login fail");
}
}
});
userService.login("tml","123");
}
- 策略模式
- 策略模式通常和工厂方法一起使用,策略模式重点在于灵活选择,工厂方法在于创建实例
- 实现:缓存本地, if else(一个是代码写死,一个是配置文件,读取,动态);通过关系表,避免if else
public interface Strategy {
void algorithmInterface();
}
public class ConcernStrategyA implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("ConcernStrategyA");
}
}
public class ConcernStrategyB implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("ConcernStrategyB");
}
}
public class ConcernStrategyC implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("ConcernStrategyB");
}
}
//缓存 查表法 避免if else
public class StrategyFactory {
private static Map strategies = new HashMap<>();
static {
strategies.put("A",new ConcernStrategyA());
strategies.put("B",new ConcernStrategyA());
strategies.put("C",new ConcernStrategyA());
}
public static Strategy getStrategy(String type){
if (type == null || type.isEmpty()){
throw new IllegalArgumentException("type should not be empty");
}else {
return strategies.get(type);
}
}
}
// if else
public class StrategyFactory1 {
public static Strategy getStrategy(String type){
if (type == null || type.isEmpty()){
throw new IllegalArgumentException("type should not be empty");
}else {
if ("A".equals(type)){
return new ConcernStrategyA();
}else if("B".equals(type)){
return new ConcernStrategyB();
}else if ("C".equals(type)){
return new ConcernStrategyC();
}else {
return null;
}
}
}
}
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.load(new FileInputStream("./config.properties"));
String strategyType = (String) properties.get("strategy");
Strategy strategy = StrategyFactory.getStrategy(strategyType);
strategy.algorithmInterface();
Strategy strategy1 = StrategyFactory1.getStrategy("A");
strategy1.algorithmInterface();
}
//config.properties
strategy:A
- 责任链模式
- 应用:常用来开发过滤器和拦截器
- 实例:Servlet Filter、Spring Interceptor
Filter & Interceptor & AOP 相同点与不同点
Filter依赖Servlet,作用于RSET api
Interceptor 依赖Spring Framework基于反射,作用于REST api
AOP 动态代理,作用于Bean
public abstract class Handler {
Handler successor;
public Handler() {
}
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public void handle(){
boolean handle = doHandle();
if (!handle && successor != null){
successor.handle();
}
};
public abstract boolean doHandle();
}
public class HandlerA extends Handler {
@Override
public boolean doHandle() {
System.out.println("AAA");
return false;
}
}
public class HandlerB extends Handler {
@Override
public boolean doHandle() {
System.out.println("BBB");
return false;
}
}
public class HandleChain {
private Handler head = null;
private Handler tail = null;
public void addHandle(Handler handler){
handler.setSuccessor(null);
if (head == null){
head = handler;
tail = handler;
return;
}
tail.setSuccessor(handler);
tail = handler;
}
public void handle(){
if (head != null){
head.handle();
}
}
}
public static void main(String[] args){
HandleChain chain = new HandleChain();
chain.addHandle(new HandlerA());
chain.addHandle(new HandlerB());
chain.handle();
//还有一种直接在HandleChain存储一个列表或者数组 循环调用
}
- 状态模式
- 分支逻辑:if else 适合状态比较少
- 查表法:二维数组,状态转移比较简单
- 状态模式:相互耦合,适合事件触发比较复杂
public enum State {//状态
Small(0),Super(1),Cape(2),Fire(3);
private int state;
State(int state) {
this.state = state;
}
public int getState() {
return state;
}
}
public interface StateMachine {
void obtainMushRoom();
void obtainCap();
void obtainFireFlower();
void meetMonster();
}
// 方式一if else
public class MarioStateMachine implements StateMachine{
State state = State.Small;
int score;
public void obtainMushRoom(){
state = State.Super;
score +=100;
}
public void obtainCap(){
if (state == State.Small){
state = State.Cape;
score +=200;
}else if(state == State.Super){
state = State.Cape;
score +=200;
}
}
public void obtainFireFlower(){//事件
if (state == State.Small){
state = State.Fire;
score +=300;
}else if(state == State.Super){
state = State.Fire;
score +=300;
}
}
public void meetMonster(){
if (state == State.Super){
state = State.Small;
score -=100;
}else if(state == State.Cape){
state = State.Small;
score -=200;
}else if (state == State.Fire){
state = State.Small;
score -=300;
}
}
}
public enum Event {
GOT_MushRoom(0),GOT_Cap(1),GOT_FireFlower(2),MEET_Monster(3);
private int event;
Event(int event) {
this.event = event;
}
public int getEvent() {
return event;
}
}
//方式二 查表法
public class MarioStateMachine1 implements StateMachine{
private int score;
private State currentState;
private static final State[][] transitionTable = {{State.Super,State.Cape,State.Fire,State.Small},
{State.Super,State.Cape,State.Fire,State.Small},
{State.Cape,State.Cape,State.Cape,State.Small},
{State.Fire,State.Fire,State.Fire,State.Small}};
private static final int[][] actionTable = {{+100,+200,+300,+0},
{+0,+300,+200,-100},
{+0,+0,+0,-200},
{+0,+0,+0,-300}};
@Override
public void obtainMushRoom() {
executeEvent(Event.GOT_MushRoom);
}
@Override
public void obtainCap() {
executeEvent(Event.GOT_Cap);
}
@Override
public void obtainFireFlower() {
executeEvent(Event.GOT_FireFlower);
}
@Override
public void meetMonster() {
executeEvent(Event.MEET_Monster);
}
public void executeEvent(Event event){
int event1 = event.getEvent();
int state = currentState.getState();
this.currentState = transitionTable[event1][state];
this.score = score + actionTable[event1][state];
}
}
public interface IMario {
State getName();
void obtainMushRoom();
void obtainCap();
void obtainFireFlower();
void meetMonster();
}
//CapMario 等代码相似,省略
public class SmallMario implements IMario {
private MarioStateMachine2 marioStateMachine;
public SmallMario(MarioStateMachine2 marioStateMachine) {
this.marioStateMachine = marioStateMachine;
}
@Override
public State getName() {
return State.Small;
}
@Override
public void obtainMushRoom() {
marioStateMachine.setMario(new SmallMario(marioStateMachine));
marioStateMachine.setScore(marioStateMachine.getScore() + 100);
}
@Override
public void obtainCap() {
}
@Override
public void obtainFireFlower() {
}
@Override
public void meetMonster() {
}
}
//方式三 状态模式
public class MarioStateMachine2 {
//省略一些代码
private int score;
private IMario mario;
public int getScore() {
return score;
}
public IMario getMario() {
return mario;
}
public void setScore(int score) {
this.score = score;
}
public void setMario(IMario mario) {
this.mario = mario;
}
}
- 迭代器模式
- ArrayIterator ArrayList 两者组合
比较:for 、foreach(语法糖,底层是Iterator)、Iterator
对于数组列表三者方式都可以,但是对于复杂的数据结构,比如图,树,就不太方便
迭代器,增删元素有时候会导致出现异常,比较常用的处理方式是增删操作报错
迭代器有remove方法,遍历结合的时候可以安全的删除
可以采用为集合生产快照的方式来避免增删出错
- 访问模式
将对象与操作解耦具体的操作,抽象一个操作类,然后传入具体的操作类实现
允许一个或多个操作应用在一组对象上,实现操作和对象解耦
ps:重载在大部分面向对象语言是静态绑定的,也就是说,调用类的哪个重载函数,是在编 译期间,由参数的声明类型决定的,而非运行时,根据参数的实际类型决定的
由于代码难以理解,所以一般不建议使用
public Class abstract ResourceFile{
String filePath;
public ResourceFile(String filePath){
this.filePath = filePath
}
abstract void accept(Visitor visitor)
}
public Class PdfFile extends ResourceFile{
public PdfFile(String filePath) {
super(filePath);
}
void accept(Visitor visitor){
visitor.visit(this)
}
}
public Class WordFile extends ResourceFile{
public PdfFile(String filePath) {
super(filePath);
}
void accept(Visitor visitor){
visitor.visit(this)
}
}
public Interface Visitor{
void visit(PdfFile pdfFile);
void visit(WordFile wordFile);
}
//读取文件
public class Extractor implements Visitor{
void visit(PdfFile pdfFile){
//......
}
void visit(WordFile wordFile){
//......
}
}
//压缩文件
public class Compressor mplements Visitor{
void visit(PdfFile pdfFile){
//......
}
void visit(WordFile wordFile){
//......
}
}
public static void main(String[] args){
Extractor extractor = new Extractor();
Compressor compressor =new Compressor();
List files = loadFiles();
for(ResourceFile file : files){
file.accept(extractor)
file.accept(compressor)
}
}
- 备忘录模式
- 命令模式
- 解释器模式
- 中介模式