博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之行为型模式
阅读量:4224 次
发布时间:2019-05-26

本文共 25035 字,大约阅读时间需要 83 分钟。

责任链(Chain Of Responsibility)

Intent

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。

Class Diagram

发出请求的客户端并不知道当中哪个对象会最终处理这个请求,对于一个具体的处理者(handler),如果可以处理该请求,则处理之,否则就将该请求转发给它的后继者。

  • Handler:定义处理请求的接口,并且实现后继链(successor)

Implementation

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 ConcreteHandler1request2 is handle by ConcreteHandler2

JDK

案例

servlet中的Filter类的核心是传递FilterChain对象,这个对象保存了到最终Servlet对象的所有Filter对象,这些对象都保存在ApplicationFilterChain对象的filters数组中。FilterChain链上每执行一个Filter对象,数组计数器加1,直到遍历完毕。

public final class ApplicationFilterChain implements FilterChain {
private int pos = 0; //当前执行filter的offset private int n; //当前filter的数量 private ApplicationFilterConfig[] filters; //filter配置类,通过getFilter()方法获取Filter private Servlet servlet @Override public void doFilter(ServletRequest request, ServletResponse response) {
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++]; Filter filter = filterConfig.getFilter(); filter.doFilter(request, response, this); } else {
// filter都处理完毕后,执行servlet servlet.service(request, response); } } }

命令(Command)

Intent

将命令封装成对象中,具有以下作用:

  • 使用命令来参数化其它对象
  • 将命令放入队列中进行排队
  • 将命令的操作记录到日志中
  • 支持可撤销的操作

Class Diagram

  • Command:命令
  • Receiver:命令接收者,也就是命令真正的执行者
  • Invoker:通过它来调用命令
  • Client:可以设置命令与命令的接收者

Implementation

设计一个遥控器,可以控制电灯开关。

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); }}

JDK

解释器(Interpreter)

Intent

为语言创建解释器,通常由语言的语法和语法分析来定义。

Class Diagram

  • TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。
  • Context:上下文,包含解释器之外的一些全局信息。

Implementation

以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。

例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。

这里的 Context 指的是 String。

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)); }}
truefalse

JDK

  • All subclasses of

迭代器(Iterator)

Intent

提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。

Class Diagram

  • Aggregate 是聚合类,其中 createIterator() 方法可以产生一个 Iterator;
  • Iterator 主要定义了 hasNext() 和 next() 方法。
  • Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。

Implementation

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
(items); }}
public interface Iterator
{
Item next(); boolean hasNext();}
public class ConcreteIterator
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
iterator = aggregate.createIterator(); while (iterator.hasNext()) {
System.out.println(iterator.next()); } }}

JDK

中介者(Mediator)

Intent

如果多个对象之间交互复杂,用一个中介对象来封装一系列对象的交互,从而使其耦合松散。每个具体的同事对象彼此不认识,只认识中介者,而中介者需要认识所有同事,从具体同事接收消息,向具体的同事发出指令。

Class Diagram

  • Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。
  • Colleague:同事,相关对象

Implementation

Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构:

使用中介者模式可以将复杂的依赖结构变成星形结构:

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()

JDK

  • All scheduleXXX() methods of
  • submit() and invokeXXX() methods of
  • scheduleXXX() methods of

备忘录(Memento)

Intent

在不违反封装的情况下获得对象的内部状态,并在该对象之外保存这个状态,从而在需要时可以将对象恢复到最初状态,可以类比游戏存档。

Class Diagram

  • Originator:原始对象
  • Caretaker:负责保存好备忘录
  • Menento:备忘录,存储原始对象的的状态。 备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。

Implementation

参考https://www.runoob.com/design-pattern/memento-pattern.html

观察者(Observer)

Intent

观察者模式定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象状态改变时,会通知所有观察者对象,使它们能够自动更新自己。 主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。

Class Diagram

主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。

观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。

Implementation

天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。

public interface Subject {
void registerObserver(Observer o); void removeObserver(Observer o); void notifyObserver();}
public class WeatherData implements Subject {
private List
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.0StatisticsDisplay.update: 0.0 0.0 0.0CurrentConditionsDisplay.update: 1.0 1.0 1.0StatisticsDisplay.update: 1.0 1.0 1.0

JDK

状态(State)

Intent

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。 状态模式主要解决的是当控制一个对象转换的条件表达式过于复杂时,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

Class Diagram

Implementation

糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。

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 quarterYou turned...A gumball comes rolling out the slot...You insert a quarterQuarter returnedYou turned, but there's no quarterYou need to pay firstYou insert a quarterYou turned...A gumball comes rolling out the slot...You insert a quarterYou turned...A gumball comes rolling out the slot...You haven't insert a quarterYou insert a quarterYou can't insert another quarterYou turned...A gumball comes rolling out the slot...You insert a quarterYou turned...A gumball comes rolling out the slot...Oops, out of gumballsYou can't insert a quarter, the machine is sold outYou turned, but there are no gumballsNo gumball dispensed

策略(Strategy)

Intent

定义一系列算法,封装每个算法,并使它们可以互换,此模式让算法的变化不会影响到使用算法的客户端。

策略模式可以让算法独立于使用它的客户端。

Class Diagram

  • Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。
  • Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。

与状态模式的比较

状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。

状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为;而策略模式主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 Context 使用的算法。

Implementation

设计一个鸭子,它可以动态地改变叫声。这里的算法族是鸭子的叫声行为。

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!

JDK

  • java.util.Comparator#compare()
  • javax.servlet.http.HttpServlet
  • javax.servlet.Filter#doFilter()

模板方法(Template Method)

Intent

定义算法框架,并将一些步骤的实现延迟到子类。

通过模板方法,子类可以重新定义算法的某些步骤,而不用改变算法的结构。

Class Diagram

Implementation

冲咖啡和冲茶都有类似的流程,但是某些步骤会有点不一样,要求复用那些相同步骤的代码。

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(); }}
boilWaterCoffee.brewpourInCupCoffee.addCondiments-----------boilWaterTea.brewpourInCupTea.addCondiments

JDK

  • java.util.Collections#sort()
  • java.io.InputStream#skip()
  • java.io.InputStream#read()
  • java.util.AbstractList#indexOf()

访问者(Visitor)

Intent

表示一个作用于某对象结构中的各元素的操作,它可以使你在不改变各元素的类的前提下定义作用于这些元素的新操作。

Class Diagram

  • Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作
  • ConcreteVisitor:具体访问者,存储遍历过程中的累计结果
  • ObjectStructure:对象结构,可以是组合结构,或者是一个集合。

转载地址:http://xxgmi.baihongyu.com/

你可能感兴趣的文章
缩放系数计算
查看>>
cocos2dx --- 按钮点击居中放大
查看>>
cocos2dx menu位置计算
查看>>
cocos2dx资源加载机制(同步/异步)
查看>>
cocos2dx C++调用java -- 字符串传递
查看>>
git学习网站
查看>>
JavaScript 学习网站
查看>>
cocos2dx java调用c++ -- 字符串传递
查看>>
CCScaleTo与CCScaleBy比较
查看>>
cocos2dx CCObject引用计数,内存释放分析(1)
查看>>
cocos2dx2.X 编译时,传递编译选项
查看>>
ccCArray.cpp 文件
查看>>
cocos2dx 屏幕大小
查看>>
libgdx: 2D Particle Editor工具使用
查看>>
eclipse 给jar库添加源码
查看>>
C++ 枚举声明 enum 和 enum class
查看>>
Python optionParser模块的使用方法
查看>>
android 消灭星星出错
查看>>
PyCharm 教程(三)Hello world!
查看>>
PyCharm: 显示源码行号
查看>>