1.观察者模式
应用:多个对象依赖于一个对象时,能有效保证解耦;
特点:建立一种一对多的关系,一个对象发生变化其余对象都能知道并更新(JDK内置);
角色:Observable——抽象主题,被观察角色(JDK内置)
Observer——抽象观察者(JDK内置,内置为接口);
java版本:
//具体观察者
public class ConcreteObserver implements Observer {
public String mName;
public ConcreteObserver (String name) {
mName = name;
}
@Override
public void update(Observable o,Object arg) {
Syetem.out.println("Hi,"+ mName +“,更新了,内容:”+ arg);
}
}
//具体主题
public class RealSubject extends Observable {
public void postNewContent(String content) {
setChanget();//内置函数,表明标识或状态发送变化;
notifyObservers(content);//内置函数将新内容通知给所有观察者,content与update方法中的Object arg参数对应
}
}
//测试
public class Test {
public static void main(String[] args) {
ConcreteObserver concreteObserver1 = new ConcreteObserver ("A");
ConcreteObserver concreteObserver2 = new ConcreteObserver ("B");
ConcreteObserver concreteObserver3 = new ConcreteObserver ("C");
RealSubject realSubject = new RealSubject();
realSubject.addObserver(concreteObserver1 );//内置方法
realSubject.addObserver(concreteObserver2 );
realSubject.addObserver(concreteObserver3 );
realSubject.postNewContent("观察者模式测试");
}
kotlin版本:
class Test(var listener:(value:Int) -> Unit) {
listener.invoke(value)
var callBack : (result: String) -> Unit = {
}
}
val test = Test {
//对value进行处理
callBack = {
//对result值处理
}
}
2.状态机模式
要素:状态枚举、事件枚举、转换列表、事件函数(一总多分、具体执行有转换列表决定)
C语言模式:
#include <iostream>
#include <stdio.h>
//状态和事件的枚举
typedef enum states_tag { STOPPED, STARTED, SPLITTED, STATES_COUNT} state_t;
typedef enum events_tag { STOP, START, SPLIT, EVENTS_COUNT } event_t;
//state 维护当前状态
typedef struct watch_state {
/* States */
state_t current_state;
}watch_state_t;
//fun 事件处理函数
void sm_error(watch_state_t* state, event_t evt);
void sm_start(watch_state_t* state, event_t evt);
void sm_stop(watch_state_t* state, event_t evt);
void sm_split(watch_state_t* state, event_t evt);
void handle_event(watch_state_t* state, event_t evt);
//state machine状态机的转换关系——二元数组维持
typedef void (*action_fn)(watch_state_t* state, event_t evt);
typedef struct state {
state_t tag;
action_fn action[EVENTS_COUNT];
} state_machine_t;
static state_machine_t sm[] = {
// state ->STOP ->START ->SPLIT
{ STOPPED, { sm_error, sm_start, sm_error }},
{ STARTED, { sm_stop, sm_error, sm_split }},
{ SPLITTED, { sm_stop, sm_error, sm_error }}
};
//name
static const char* states_name[] = { "STOPPED", "STARTED", "SPLITTED", "UNKNOWN" };
static const char* events_name[] = { "STOP", "START", "SPLIT", "UNKNOWN" };
static const char* state_to_string(state_t state)
{
return (state < STATES_COUNT) ? states_name[state] : states_name[STATES_COUNT];
}
static const char* event_to_string(event_t event)
{
return (event < EVENTS_COUNT) ? events_name[event] : events_name[EVENTS_COUNT];
}
//init
void init(watch_state_t* state) {
state->current_state = STOPPED;
printf("sm init\n");
}
int main()
{
watch_state_t sw;;
init(&sw);
handle_event(&sw, STOP);
handle_event(&sw, SPLIT);
handle_event(&sw, START);
handle_event(&sw, START);
handle_event(&sw, SPLIT);
handle_event(&sw, SPLIT);
handle_event(&sw, STOP);
handle_event(&sw, SPLIT);
handle_event(&sw, START);
handle_event(&sw, STOP);
}
//handle
void handle_event(watch_state_t* state, event_t evt) {
if (evt >= EVENTS_COUNT || state->current_state >= STATES_COUNT) {
sm_error(state, evt);
}
sm[state->current_state].action[evt](state, evt);
}
//function
void sm_error(watch_state_t* state, event_t evt) {
state_t cur = state->current_state;
printf("error, cur:%s, event:%s\n", state_to_string(cur), event_to_string(evt));
}
void sm_start(watch_state_t* state, event_t evt) {
state_t pre = state->current_state;
state->current_state = STARTED;
state_t cur = state->current_state;
printf("pre:%s, cur:%s, event:%s\n", state_to_string(pre), state_to_string(cur), event_to_string(evt));
}
void sm_stop(watch_state_t* state, event_t evt) {
state_t pre = state->current_state;
state->current_state = STOPPED;
state_t cur = state->current_state;
printf("pre:%s, cur:%s, event:%s\n", state_to_string(pre), state_to_string(cur), event_to_string(evt));
}
void sm_split(watch_state_t* state, event_t evt) {
state_t pre = state->current_state;
state->current_state = SPLITTED;
state_t cur = state->current_state;
printf("pre:%s, cur:%s, event:%s\n", state_to_string(pre), state_to_string(cur), event_to_string(evt));
}
执行结果:
JAVA模式:
// 事件枚举
enum Event {
ON, OFF
}
public interface TvState{
public void nextChannel();
public void prevChannel();
public void turnUp();
public void turnDown();
}
public class PowerOnState implements TvState{
@Override
public void nextChannel(){
print("下一个频道");
}
@Override
public void prevChannel(){
print("上一个频道");
}
@Override
public void turnUp(){
print("调大音量");
}
@Override
public void turnDown(){
print("调小音量");
}
}
public class PowerOffState implements TvState{
@Override
public void nextChannel(){
}
@Override
public void prevChannel(){
}
@Override
public void turnUp(){
}
@Override
public void turnDown(){
}
}
class StateEventPair {
private TvState state;
private Event event;
public StateEventPair(TvState state, Event event) {
this.state = state;
this.event = event;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StateEventPair that = (StateEventPair) o;
return state == that.state && event == that.event;
}
@Override
public int hashCode() {
return Objects.hash(state, event);
}
}
/**
*具体的事件处理函数,此处未实现
**/
public interface SmHandle {
public void handleEvent();
}
public class StateMachine {
private Map<StateEventPair, Pair<SmHandle, TvState>> stateTransitions = new HashMap<>();
private TvState currentState;
public StateMachine(TvState initialState) {
this.currentState = initialState;
}
public TvState getState() {
return currentState;
}
// 定义状态转移
public void addTransition(TvState state, Event event, SmHandle smHandle, TvState endState) {
stateTransitions.put(new StateEventPair(state, event), new Pair<>(smHandle, endState));
}
// 处理事件,驱动状态转移
public void handleEvent(Event event) {
StateEventPair stateEventPair = new StateEventPair(currentState, event);
if (stateTransitions.containsKey(stateEventPair)) {
Pair stateUpdate = stateTransitions.get(stateEventPair);
((SmHandle) stateUpdate.first).handleEvent();//handle
currentState = (TvState) stateUpdate.second;//update state
} else {
System.out.println("No transition defined for " + currentState + " on event " + event);
}
}
}
public class Main {
public static void main(String[] args) {
PowerOnState onState = new PowerOnState();
PowerOffState offState = new PowerOffState();
SmHandle smHandle = new SmHandle();//实际无法初始化,待传入具体的事件处理函数
StateMachine stateMachine = new StateMachine(new PowerOffState());
// 添加状态转移
stateMachine.addTransition(onState, OFF, smHandle, offState);
stateMachine.addTransition(offState, ON, smHandle, onState);
// 触发事件,驱动状态转移
stateMachine.handleEvent(ON); //开机
TvState tv = stateMachine.getState();
tv.nextChannel();//下一个频道
tv.turnUp();//调大音量
stateMachine.handleEvent(OFF);
TvState tv = stateMachine.getState();
tv.prevChannel();//上一个频道无效,关机后所有操作无效
}
}
3.模板模式
制定一个算法框架,让不同的对象有不同的实现方式
/**
* 算法框架
*/
public abstract class Drinks {
private String TAG = "Drinks";
//框架
public void prepareDrinks(){
prepareWater();
addResource();
}
//相同的实现方式
void prepareWater() {
Log.d(TAG,"Prepare water");
}
//不同的实现方式
abstract void addResource();
}
public class DrinkCoffee extends Drinks{
private String TAG = "DrinkCoffee";
@Override
void addResource() {
Log.d(TAG,"Add coffee");
}
}
public class DrinkTea extends Drinks{
private String TAG = "DrinkTea";
@Override
void addResource() {
Log.d(TAG,"Add tea");
}
}
Drinks tea = new DrinkTea();
tea.prepareDrinks();
Drinks coffee = new DrinkCoffee();
coffee.prepareDrinks();
4.策略模式
相同的接口方法、不同的实现
/**
* 同一个接口
*/
public interface CalculatorStrategy {
public void calculate(int a,int b);
}
/**
* 接口的不同实现
*/
public class AddCalculator implements CalculatorStrategy {
private String TAG = "AddCalculator";
@Override
public void calculate(int a, int b) {
Log.d(TAG, "a + b = " + (a + b));
}
}
/**
* 接口的不同实现
*/
public class SubCalculator implements CalculatorStrategy{
private String TAG = "SubCalculator";
@Override
public void calculate(int a, int b) {
Log.d(TAG, "a + b = " + (a - b));
}
}
/**
* 不同策略实现
*/
public class Calculator {
private CalculatorStrategy calculatorStrategy;
public Calculator(CalculatorStrategy calculatorStrategy) {
this.calculatorStrategy = calculatorStrategy;
}
public void setCalculatorStrategy(CalculatorStrategy calculatorStrategy) {
this.calculatorStrategy = calculatorStrategy;
}
public void calculate(int a, int b) {
calculatorStrategy.calculate(a, b);
}
}
使用:
val calculator = Calculator(AddCalculator())
calculator.calculate(5,3)
calculator.setCalculatorStrategy(SubCalculator())
calculator.calculate(5,3)