使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。html
public abstract class Handler { protected Handler successor; public Handler(Handler successor) { this.successor = successor; } protected abstract void handleRequest(Request request); } public class ConcreteHandler1 extends Handler { public ConcreteHandler1(Handler successor) { super(successor); } @Override protected void handleRequest(Request request) { if (request.getType() == RequestType.TYPE1) { System.out.println(request.getName() + " is handle by ConcreteHandler1"); return; } if (successor != null) { successor.handleRequest(request); } } } public class ConcreteHandler2 extends Handler { public ConcreteHandler2(Handler successor) { super(successor); } @Override protected void handleRequest(Request request) { if (request.getType() == RequestType.TYPE2) { System.out.println(request.getName() + " is handle by ConcreteHandler2"); return; } if (successor != null) { successor.handleRequest(request); } } } public class Request { private RequestType type; private String name; public Request(RequestType type, String name) { this.type = type; this.name = name; } public RequestType getType() { return type; } public String getName() { return name; } } public enum RequestType { TYPE1, TYPE2 } public class Client { public static void main(String[] args) { Handler handler1 = new ConcreteHandler1(null); Handler handler2 = new ConcreteHandler2(handler1); Request request1 = new Request(RequestType.TYPE1, "request1"); handler2.handleRequest(request1); Request request2 = new Request(RequestType.TYPE2, "request2"); handler2.handleRequest(request2); } } request1 is handle by ConcreteHandler1 request2 is handle by ConcreteHandler2
将命令封装成对象中,具备如下做用:java
设计一个遥控器,能够控制电灯开关。git
public interface Command { void execute(); } public class LightOnCommand implements Command { Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.on(); } } public class LightOffCommand implements Command { Light light; public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.off(); } } public class Light { public void on() { System.out.println("Light is on!"); } public void off() { System.out.println("Light is off!"); } } /** * 遥控器 */ public class Invoker { private Command[] onCommands; private Command[] offCommands; private final int slotNum = 7; public Invoker() { this.onCommands = new Command[slotNum]; this.offCommands = new Command[slotNum]; } public void setOnCommand(Command command, int slot) { onCommands[slot] = command; } public void setOffCommand(Command command, int slot) { offCommands[slot] = command; } public void onButtonWasPushed(int slot) { onCommands[slot].execute(); } public void offButtonWasPushed(int slot) { offCommands[slot].execute(); } } public class Client { public static void main(String[] args) { Invoker invoker = new Invoker(); Light light = new Light(); Command lightOnCommand = new LightOnCommand(light); Command lightOffCommand = new LightOffCommand(light); invoker.setOnCommand(lightOnCommand, 0); invoker.setOffCommand(lightOffCommand, 0); invoker.onButtonWasPushed(0); invoker.offButtonWasPushed(0); } }
为语言建立解释器,一般由语言的语法和语法分析来定义。github
如下是一个规则检验器实现,具备 and 和 or 规则,经过规则能够构建一颗解析树,用来检验一个文本是否知足解析树定义的规则。算法
例如一颗解析树为 D And (A Or (B C)),文本 "D A" 知足该解析树定义的规则。express
这里的 Context 指的是 String。apache
public abstract class Expression { public abstract boolean interpret(String str); } public class TerminalExpression extends Expression { private String literal = null; public TerminalExpression(String str) { literal = str; } public boolean interpret(String str) { StringTokenizer st = new StringTokenizer(str); while (st.hasMoreTokens()) { String test = st.nextToken(); if (test.equals(literal)) { return true; } } return false; } } public class AndExpression extends Expression { private Expression expression1 = null; private Expression expression2 = null; public AndExpression(Expression expression1, Expression expression2) { this.expression1 = expression1; this.expression2 = expression2; } public boolean interpret(String str) { return expression1.interpret(str) && expression2.interpret(str); } } public class OrExpression extends Expression { private Expression expression1 = null; private Expression expression2 = null; public OrExpression(Expression expression1, Expression expression2) { this.expression1 = expression1; this.expression2 = expression2; } public boolean interpret(String str) { return expression1.interpret(str) || expression2.interpret(str); } } public class Client { /** * 构建解析树 */ public static Expression buildInterpreterTree() { // Literal Expression terminal1 = new TerminalExpression("A"); Expression terminal2 = new TerminalExpression("B"); Expression terminal3 = new TerminalExpression("C"); Expression terminal4 = new TerminalExpression("D"); // B C Expression alternation1 = new OrExpression(terminal2, terminal3); // A Or (B C) Expression alternation2 = new OrExpression(terminal1, alternation1); // D And (A Or (B C)) return new AndExpression(terminal4, alternation2); } public static void main(String[] args) { Expression define = buildInterpreterTree(); String context1 = "D A"; String context2 = "A B"; System.out.println(define.interpret(context1)); System.out.println(define.interpret(context2)); } } true false
提供一种顺序访问聚合对象元素的方法,而且不暴露聚合对象的内部表示。api
public interface Aggregate { Iterator createIterator(); } public class ConcreteAggregate implements Aggregate { private Integer[] items; public ConcreteAggregate() { items = new Integer[10]; for (int i = 0; i < items.length; i++) { items[i] = i; } } @Override public Iterator createIterator() { return new ConcreteIterator<Integer>(items); } } public interface Iterator<Item> { Item next(); boolean hasNext(); } public class ConcreteIterator<Item> implements Iterator { private Item[] items; private int position = 0; public ConcreteIterator(Item[] items) { this.items = items; } @Override public Object next() { return items[position++]; } @Override public boolean hasNext() { return position < items.length; } } public class Client { public static void main(String[] args) { Aggregate aggregate = new ConcreteAggregate(); Iterator<Integer> iterator = aggregate.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
集中相关对象之间复杂的沟通和控制方式。并发
Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时须要去操做其它对象,造成了下面这种依赖结构:oracle
使用中介者模式能够将复杂的依赖结构变成星形结构:
public abstract class Colleague { public abstract void onEvent(Mediator mediator); } public class Alarm extends Colleague { @Override public void onEvent(Mediator mediator) { mediator.doEvent("alarm"); } public void doAlarm() { System.out.println("doAlarm()"); } } public class CoffeePot extends Colleague { @Override public void onEvent(Mediator mediator) { mediator.doEvent("coffeePot"); } public void doCoffeePot() { System.out.println("doCoffeePot()"); } } public class Calender extends Colleague { @Override public void onEvent(Mediator mediator) { mediator.doEvent("calender"); } public void doCalender() { System.out.println("doCalender()"); } } public class Sprinkler extends Colleague { @Override public void onEvent(Mediator mediator) { mediator.doEvent("sprinkler"); } public void doSprinkler() { System.out.println("doSprinkler()"); } } public abstract class Mediator { public abstract void doEvent(String eventType); } public class ConcreteMediator extends Mediator { private Alarm alarm; private CoffeePot coffeePot; private Calender calender; private Sprinkler sprinkler; public ConcreteMediator(Alarm alarm, CoffeePot coffeePot, Calender calender, Sprinkler sprinkler) { this.alarm = alarm; this.coffeePot = coffeePot; this.calender = calender; this.sprinkler = sprinkler; } @Override public void doEvent(String eventType) { switch (eventType) { case "alarm": doAlarmEvent(); break; case "coffeePot": doCoffeePotEvent(); break; case "calender": doCalenderEvent(); break; default: doSprinklerEvent(); } } public void doAlarmEvent() { alarm.doAlarm(); coffeePot.doCoffeePot(); calender.doCalender(); sprinkler.doSprinkler(); } public void doCoffeePotEvent() { // ... } public void doCalenderEvent() { // ... } public void doSprinklerEvent() { // ... } } public class Client { public static void main(String[] args) { Alarm alarm = new Alarm(); CoffeePot coffeePot = new CoffeePot(); Calender calender = new Calender(); Sprinkler sprinkler = new Sprinkler(); Mediator mediator = new ConcreteMediator(alarm, coffeePot, calender, sprinkler); // 闹钟事件到达,调用中介者就能够操做相关对象 alarm.onEvent(mediator); } } doAlarm() doCoffeePot() doCalender() doSprinkler()
在不违反封装的状况下得到对象的内部状态,从而在须要时能够将对象恢复到最初状态。
如下实现了一个简单计算器程序,能够输入两个值,而后计算这两个值的和。备忘录模式容许将这两个值存储起来,而后在某个时刻用存储的状态进行恢复。
实现参考:Memento Pattern - Calculator Example - Java Sourcecode
/** * Originator Interface */ public interface Calculator { // Create Memento PreviousCalculationToCareTaker backupLastCalculation(); // setMemento void restorePreviousCalculation(PreviousCalculationToCareTaker memento); int getCalculationResult(); void setFirstNumber(int firstNumber); void setSecondNumber(int secondNumber); } /** * Originator Implementation */ public class CalculatorImp implements Calculator { private int firstNumber; private int secondNumber; @Override public PreviousCalculationToCareTaker backupLastCalculation() { // create a memento object used for restoring two numbers return new PreviousCalculationImp(firstNumber, secondNumber); } @Override public void restorePreviousCalculation(PreviousCalculationToCareTaker memento) { this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber(); this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber(); } @Override public int getCalculationResult() { // result is adding two numbers return firstNumber + secondNumber; } @Override public void setFirstNumber(int firstNumber) { this.firstNumber = firstNumber; } @Override public void setSecondNumber(int secondNumber) { this.secondNumber = secondNumber; } } /** * Memento Interface to Originator * * This interface allows the originator to restore its state */ public interface PreviousCalculationToOriginator { int getFirstNumber(); int getSecondNumber(); } /** * Memento interface to CalculatorOperator (Caretaker) */ public interface PreviousCalculationToCareTaker { // no operations permitted for the caretaker } /** * Memento Object Implementation * <p> * Note that this object implements both interfaces to Originator and CareTaker */ public class PreviousCalculationImp implements PreviousCalculationToCareTaker, PreviousCalculationToOriginator { private int firstNumber; private int secondNumber; public PreviousCalculationImp(int firstNumber, int secondNumber) { this.firstNumber = firstNumber; this.secondNumber = secondNumber; } @Override public int getFirstNumber() { return firstNumber; } @Override public int getSecondNumber() { return secondNumber; } } /** * CareTaker object */ public class Client { public static void main(String[] args) { // program starts Calculator calculator = new CalculatorImp(); // assume user enters two numbers calculator.setFirstNumber(10); calculator.setSecondNumber(100); // find result System.out.println(calculator.getCalculationResult()); // Store result of this calculation in case of error PreviousCalculationToCareTaker memento = calculator.backupLastCalculation(); // user enters a number calculator.setFirstNumber(17); // user enters a wrong second number and calculates result calculator.setSecondNumber(-290); // calculate result System.out.println(calculator.getCalculationResult()); // user hits CTRL + Z to undo last operation and see last result calculator.restorePreviousCalculation(memento); // result restored System.out.println(calculator.getCalculationResult()); } } 110 -273 110
定义对象之间的一对多依赖,当一个对象状态改变时,它的全部依赖都会收到通知而且自动更新状态。
主题(Subject)是被观察的对象,而其全部依赖者(Observer)称为观察者。
主题(Subject)具备注册和移除观察者、并通知全部观察者的功能,主题是经过维护一张观察者列表来实现这些操做的。
观察者(Observer)的注册功能须要调用主题的 registerObserver() 方法。
天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,而且在未来会继续增长。
public interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObserver(); } public class WeatherData implements Subject { private List<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList<>(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; notifyObserver(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } @Override public void notifyObserver() { for (Observer o : observers) { o.update(temperature, humidity, pressure); } } } public interface Observer { void update(float temp, float humidity, float pressure); } public class StatisticsDisplay implements Observer { public StatisticsDisplay(Subject weatherData) { weatherData.reisterObserver(this); } @Override public void update(float temp, float humidity, float pressure) { System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure); } } public class CurrentConditionsDisplay implements Observer { public CurrentConditionsDisplay(Subject weatherData) { weatherData.registerObserver(this); } @Override public void update(float temp, float humidity, float pressure) { System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure); } } public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); weatherData.setMeasurements(0, 0, 0); weatherData.setMeasurements(1, 1, 1); } } CurrentConditionsDisplay.update: 0.0 0.0 0.0 StatisticsDisplay.update: 0.0 0.0 0.0 CurrentConditionsDisplay.update: 1.0 1.0 1.0 StatisticsDisplay.update: 1.0 1.0 1.0
容许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。
糖果销售机有多种状态,每种状态下销售机有不一样的行为,状态能够发生转移,使得销售机的行为也发生改变。
public interface State { /** * 投入 25 分钱 */ void insertQuarter(); /** * 退回 25 分钱 */ void ejectQuarter(); /** * 转动曲柄 */ void turnCrank(); /** * 发放糖果 */ void dispense(); } public class HasQuarterState implements State { private GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("You can't insert another quarter"); } @Override public void ejectQuarter() { System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } @Override public void turnCrank() { System.out.println("You turned..."); gumballMachine.setState(gumballMachine.getSoldState()); } @Override public void dispense() { System.out.println("No gumball dispensed"); } } public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("You insert a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } @Override public void ejectQuarter() { System.out.println("You haven't insert a quarter"); } @Override public void turnCrank() { System.out.println("You turned, but there's no quarter"); } @Override public void dispense() { System.out.println("You need to pay first"); } } public class SoldOutState implements State { GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("You can't insert a quarter, the machine is sold out"); } @Override public void ejectQuarter() { System.out.println("You can't eject, you haven't inserted a quarter yet"); } @Override public void turnCrank() { System.out.println("You turned, but there are no gumballs"); } @Override public void dispense() { System.out.println("No gumball dispensed"); } } public class SoldState implements State { GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("Please wait, we're already giving you a gumball"); } @Override public void ejectQuarter() { System.out.println("Sorry, you already turned the crank"); } @Override public void turnCrank() { System.out.println("Turning twice doesn't get you another gumball!"); } @Override public void dispense() { gumballMachine.releaseBall(); if (gumballMachine.getCount() > 0) { gumballMachine.setState(gumballMachine.getNoQuarterState()); } else { System.out.println("Oops, out of gumballs"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } } public class GumballMachine { private State soldOutState; private State noQuarterState; private State hasQuarterState; private State soldState; private State state; private int count = 0; public GumballMachine(int numberGumballs) { count = numberGumballs; soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); if (numberGumballs > 0) { state = noQuarterState; } else { state = soldOutState; } } public void insertQuarter() { state.insertQuarter(); } public void ejectQuarter() { state.ejectQuarter(); } public void turnCrank() { state.turnCrank(); state.dispense(); } public void setState(State state) { this.state = state; } public void releaseBall() { System.out.println("A gumball comes rolling out the slot..."); if (count != 0) { count -= 1; } } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public int getCount() { return count; } } public class Client { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(5); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.ejectQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.ejectQuarter(); gumballMachine.insertQuarter(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); } } You insert a quarter You turned... A gumball comes rolling out the slot... You insert a quarter Quarter returned You turned, but there's no quarter You need to pay first You insert a quarter You turned... A gumball comes rolling out the slot... You insert a quarter You turned... A gumball comes rolling out the slot... You haven't insert a quarter You insert a quarter You can't insert another quarter You turned... A gumball comes rolling out the slot... You insert a quarter You turned... A gumball comes rolling out the slot... Oops, out of gumballs You can't insert a quarter, the machine is sold out You turned, but there are no gumballs No gumball dispensed
定义一系列算法,封装每一个算法,并使它们能够互换。
策略模式可让算法独立于使用它的客户端。
状态模式的类图和策略模式相似,而且都是可以动态改变对象的行为。可是状态模式是经过状态转移来改变 Context 所组合的 State 对象,而策略模式是经过 Context 自己的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程当中因为一些条件发生改变而使得 State 对象发生改变,注意必需要是在运行过程当中。
状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为;而策略模式主要是用来封装一组能够互相替代的算法族,而且能够根据须要动态地去替换 Context 使用的算法。
设计一个鸭子,它能够动态地改变叫声。这里的算法族是鸭子的叫声行为。
public interface QuackBehavior { void quack(); } public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("quack!"); } } public class Squeak implements QuackBehavior{ @Override public void quack() { System.out.println("squeak!"); } } public class Duck { private QuackBehavior quackBehavior; public void performQuack() { if (quackBehavior != null) { quackBehavior.quack(); } } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } } public class Client { public static void main(String[] args) { Duck duck = new Duck(); duck.setQuackBehavior(new Squeak()); duck.performQuack(); duck.setQuackBehavior(new Quack()); duck.performQuack(); } } squeak! quack!
定义算法框架,并将一些步骤的实现延迟到子类。
经过模板方法,子类能够从新定义算法的某些步骤,而不用改变算法的结构。
冲咖啡和冲茶都有相似的流程,可是某些步骤会有点不同,要求复用那些相同步骤的代码。
public abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("boilWater"); } void pourInCup() { System.out.println("pourInCup"); } } public class Coffee extends CaffeineBeverage { @Override void brew() { System.out.println("Coffee.brew"); } @Override void addCondiments() { System.out.println("Coffee.addCondiments"); } } public class Tea extends CaffeineBeverage { @Override void brew() { System.out.println("Tea.brew"); } @Override void addCondiments() { System.out.println("Tea.addCondiments"); } } public class Client { public static void main(String[] args) { CaffeineBeverage caffeineBeverage = new Coffee(); caffeineBeverage.prepareRecipe(); System.out.println("-----------"); caffeineBeverage = new Tea(); caffeineBeverage.prepareRecipe(); } } boilWater Coffee.brew pourInCup Coffee.addCondiments ----------- boilWater Tea.brew pourInCup Tea.addCondiments
为一个对象结构(好比组合结构)增长新能力。
public interface Element { void accept(Visitor visitor); } class CustomerGroup { private List<Customer> customers = new ArrayList<>(); void accept(Visitor visitor) { for (Customer customer : customers) { customer.accept(visitor); } } void addCustomer(Customer customer) { customers.add(customer); } } public class Customer implements Element { private String name; private List<Order> orders = new ArrayList<>(); Customer(String name) { this.name = name; } String getName() { return name; } void addOrder(Order order) { orders.add(order); } public void accept(Visitor visitor) { visitor.visit(this); for (Order order : orders) { order.accept(visitor); } } } public class Order implements Element { private String name; private List<Item> items = new ArrayList(); Order(String name) { this.name = name; } Order(String name, String itemName) { this.name = name; this.addItem(new Item(itemName)); } String getName() { return name; } void addItem(Item item) { items.add(item); } public void accept(Visitor visitor) { visitor.visit(this); for (Item item : items) { item.accept(visitor); } } } public class Item implements Element { private String name; Item(String name) { this.name = name; } String getName() { return name; } public void accept(Visitor visitor) { visitor.visit(this); } } public interface Visitor { void visit(Customer customer); void visit(Order order); void visit(Item item); } public class GeneralReport implements Visitor { private int customersNo; private int ordersNo; private int itemsNo; public void visit(Customer customer) { System.out.println(customer.getName()); customersNo++; } public void visit(Order order) { System.out.println(order.getName()); ordersNo++; } public void visit(Item item) { System.out.println(item.getName()); itemsNo++; } public void displayResults() { System.out.println("Number of customers: " + customersNo); System.out.println("Number of orders: " + ordersNo); System.out.println("Number of items: " + itemsNo); } } public class Client { public static void main(String[] args) { Customer customer1 = new Customer("customer1"); customer1.addOrder(new Order("order1", "item1")); customer1.addOrder(new Order("order2", "item1")); customer1.addOrder(new Order("order3", "item1")); Order order = new Order("order_a"); order.addItem(new Item("item_a1")); order.addItem(new Item("item_a2")); order.addItem(new Item("item_a3")); Customer customer2 = new Customer("customer2"); customer2.addOrder(order); CustomerGroup customers = new CustomerGroup(); customers.addCustomer(customer1); customers.addCustomer(customer2); GeneralReport visitor = new GeneralReport(); customers.accept(visitor); visitor.displayResults(); } } customer1 order1 item1 order2 item1 order3 item1 customer2 order_a item_a1 item_a2 item_a3 Number of customers: 2 Number of orders: 4 Number of items: 6
使用什么都不作的空对象来代替 NULL。
一个方法返回 NULL,意味着方法的调用端须要去检查返回值是不是 NULL,这么作会致使很是多的冗余的检查代码。而且若是某一个调用端忘记了作这个检查返回值,而直接使用返回的对象,那么就有可能抛出空指针异常。
public abstract class AbstractOperation { abstract void request(); } public class RealOperation extends AbstractOperation { @Override void request() { System.out.println("do something"); } } public class NullOperation extends AbstractOperation{ @Override void request() { // do nothing } } public class Client { public static void main(String[] args) { AbstractOperation abstractOperation = func(-1); abstractOperation.request(); } public static AbstractOperation func(int para) { if (para < 0) { return new NullOperation(); } return new RealOperation(); } }
本人免费整理了Java高级资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G,须要本身领取。
传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q