设计模式之命令模式(Command Pattern)
来源:互联网 发布:网络布局要看什么书籍 编辑:程序博客网 时间:2024/05/16 02:26
命令模式主要通过中介Command实现了发出命令者和命令的执行者,也即Invoke类和Receiver的松耦合。
先看类图:
将请求封装成一个对象,从而使用户使用不同的请求把客户端参数化,请求队列或者记录日志,以及支持可撤销的操作。
看一个Android的例子
先定义两种画笔,这里是额外的,也就是说更这个设计模式没有太多关系,只是程序需要:
package com.example.yale.mydrawbrush.Brush;import android.graphics.Path;/** * Created by Yale on 16/7/8. *///抽象笔触public interface IBrush { /** * 触点接触时 * @param path * @param x * @param y */ void down(Path path, float x, float y); /** * 触点移动式 * @param path * @param x * @param y */ void move(Path path, float x, float y); /** * 触点离开时 * @param path * @param x * @param y */ void up(Path path, float x, float y);}
普通触笔
package com.example.yale.mydrawbrush.Brush;import android.graphics.Path;/** * Created by Yale on 16/7/8. */public class NormalBrush implements IBrush { @Override public void down(Path path, float x, float y) { path.moveTo(x, y); } @Override public void move(Path path, float x, float y) { path.lineTo(x, y); } @Override public void up(Path path, float x, float y) { }}
圆形触笔
package com.example.yale.mydrawbrush.Brush;import android.graphics.Path;/** * Created by Yale on 16/7/8. */public class CircleBrush implements IBrush { @Override public void down(Path path, float x, float y) { } @Override public void move(Path path, float x, float y) { path.addCircle(x, y, 10, Path.Direction.CW); } @Override public void up(Path path, float x, float y) { }}
下面关键来了,我们先定义抽象命令接口,也就是绘制命令接口:
package com.example.yale.mydrawbrush.Brush;/** * Created by Yale on 16/7/8. */import android.graphics.Canvas;/** * 对于每一次路径绘制,有两个命令:绘制命令和撤销命令 */public interface IDraw { /** * 绘制命令 * @param canvas 画布对象 */ void draw(Canvas canvas); /** * 撤销命令 */ void undo();}
具体的绘制命令,也就是实现上面的接口
package com.example.yale.mydrawbrush.Brush;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;/** * Created by Yale on 16/7/8. */public class DrawPath implements IDraw { public Path path; public Paint paint; @Override public void draw(Canvas canvas) { canvas.drawPath(path, paint); } @Override public void undo() { }}
然后是命令的发出者Invoker,定义为DrawInvoker
package com.example.yale.mydrawbrush.Brush;import android.graphics.Canvas;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * Created by Yale on 16/7/8. */public class DrawInvoker { //绘制列表 private List<DrawPath> drawList = Collections.synchronizedList(new ArrayList<DrawPath>()); //重做列表 private List<DrawPath> redoList = Collections.synchronizedList(new ArrayList<DrawPath>()); public void add(DrawPath command) { redoList.clear(); drawList.add(command); } public void undo() { if (drawList.size() > 0) { DrawPath undo = drawList.get(drawList.size() - 1); drawList.remove(drawList.size() - 1); undo.undo(); redoList.add(undo); } } public void redo() { if (redoList.size() > 0) { DrawPath redoCommand = redoList.get(redoList.size() - 1); redoList.remove(redoList.size() - 1); drawList.add(redoCommand); } } public void execute(Canvas canvas) { if (drawList != null) { for (DrawPath temp : drawList) { temp.draw(canvas); } } } public boolean canRedo() { return redoList.size() > 0; } public boolean canUndo() { return drawList.size() > 0; }}
再定义命令的执行者,也就是Receiver,这里定义为DrawCanvas
package com.example.yale.mydrawbrush.Brush;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.PorterDuff;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceView;/** * Created by Yale on 16/7/8. */public class DrawCanvas extends SurfaceView implements SurfaceHolder.Callback{ public boolean isDrawing, isRunning; private Bitmap mBitmap; private DrawInvoker mInvoker; private DrawThread mThread; public DrawCanvas(Context context, AttributeSet attrs) { super(context, attrs); mInvoker = new DrawInvoker(); mThread = new DrawThread(); getHolder().addCallback(this); } public void add(DrawPath path){ mInvoker.add(path); } public void redo(){ isDrawing = true; mInvoker.redo(); } public void undo(){ isDrawing = true; mInvoker.undo(); } public boolean canUndo(){ return mInvoker.canUndo(); } public boolean canRedo(){ return mInvoker.canRedo(); }// @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { isRunning = true; mThread.start(); }// @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); }// @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { boolean retry = true; isRunning = false; while(retry){ try{ mThread.join(); retry = false; }catch (Exception e){ e.printStackTrace(); } } } private class DrawThread extends Thread{ @Override public void run() { Canvas canvas = null; while(isRunning) { if (isDrawing) { try { canvas = getHolder().lockCanvas(null); if (mBitmap == null) { mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); } Canvas c = new Canvas(mBitmap); c.drawColor(0, PorterDuff.Mode.CLEAR); canvas.drawColor(0, PorterDuff.Mode.CLEAR); mInvoker.execute(c); canvas.drawBitmap(mBitmap, 0, 0, null); } finally { getHolder().unlockCanvasAndPost(canvas); } isDrawing = false; } } } }}
最后是把上述整合
package com.example.yale.mydrawbrush;import android.graphics.Paint;import android.graphics.Path;import android.os.SystemClock;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import com.example.yale.mydrawbrush.Brush.CircleBrush;import com.example.yale.mydrawbrush.Brush.DrawCanvas;import com.example.yale.mydrawbrush.Brush.DrawPath;import com.example.yale.mydrawbrush.Brush.IBrush;import com.example.yale.mydrawbrush.Brush.NormalBrush;import butterknife.Bind;import butterknife.ButterKnife;public class MainActivity extends AppCompatActivity {// private DrawCanvas mCanvas; private DrawPath mPath; private Paint mPaint; private IBrush mBrush; @Bind(R.id.ac_draw_canvas) DrawCanvas mCanvas; @Bind(R.id.ac_draw_draw_operate_undo_btn) Button btnUndo; @Bind(R.id.ac_draw_draw_operate_redo_btn) Button btnRedo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); mPaint = new Paint(); mPaint.setColor(0XFFFFFFFF); mPaint.setStrokeWidth(3); mCanvas.setOnTouchListener(new DrawTouchListener()); mBrush = new NormalBrush(); btnRedo.setEnabled(false); btnUndo.setEnabled(false); } public void onClick(View view){ switch (view.getId()){ case R.id.ac_draw_color_red_btn: mPaint = new Paint(); mPaint.setStrokeWidth(3); mPaint.setColor(0XFFFF0000); System.out.print("sfsfasfafd!$@#$!@#$!"); break; case R.id.ac_draw_color_blue_btn: mPaint = new Paint(); mPaint.setStrokeWidth(3); mPaint.setColor(0XFF00FF00); break; case R.id.ac_draw_color_green_btn: mPaint = new Paint(); mPaint.setStrokeWidth(3); mPaint.setColor(0XFF0000FF); break; case R.id.ac_draw_draw_operate_undo_btn: mCanvas.undo(); if(!mCanvas.canUndo()){ btnUndo.setEnabled(false); } btnRedo.setEnabled(true); break; case R.id.ac_draw_draw_operate_redo_btn: mCanvas.redo(); if(!mCanvas.canRedo()){ btnUndo.setEnabled(false); } btnRedo.setEnabled(true); break; case R.id.ac_draw_operate_brush_circle_btn: mBrush = new CircleBrush(); break; case R.id.ac_draw_operate_brush_normal_btn: mBrush = new NormalBrush(); break; default: break; } } private class DrawTouchListener implements View.OnTouchListener{ @Override public boolean onTouch(View view, MotionEvent motionEvent) { if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){ mPath = new DrawPath(); mPath.paint = mPaint; mPath.path = new Path(); mBrush.down(mPath.path, motionEvent.getX(), motionEvent.getY()); }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){ mBrush.move(mPath.path, motionEvent.getX(), motionEvent.getY()); }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){ mBrush.up(mPath.path, motionEvent.getX(), motionEvent.getY()); mCanvas.add(mPath); mCanvas.isDrawing = true; btnUndo.setEnabled(true); btnRedo.setEnabled(false); } return true; } }}
0 0
- 设计模式之命令模式(Command Pattern)
- 设计模式之命令模式(Command Pattern)
- 设计模式之命令模式---Command Pattern
- 命令设计模式(Command Pattern)
- 设计模式读书笔记之命令模式(Command Pattern)
- 设计模式笔记之命令模式(command Pattern)
- Php设计模式之【命令模式Command Pattern】
- 设计模式之七 命令模式(Command Pattern)
- 设计模式之七:命令模式(Command Pattern)
- 设计模式之-命令模式(Command Pattern)
- JAVA设计模式之 命令模式【Command Pattern】
- 设计模式(行为型)之命令模式(Command Pattern)
- 设计模式之:命令模式(Command Pattern)
- 设计模式读书笔记之命令模式(Command Pattern)
- 设计模式总结之Command Pattern(命令模式)
- Net设计模式实例之命令模式(Command Pattern)
- 设计模式拾荒之命令模式( Command Pattern )
- 设计模式 - Command Pattern(命令模式)
- websocket相关
- IOS树视图学习总结
- SDUT2139图结构练习——BFS——从起始点到目标点的最短步数
- 36.在Ubuntu上打造方便好用的Python开发环境
- splay模板
- 设计模式之命令模式(Command Pattern)
- JSP/SERVLET入门教程--Servlet 使用入门
- 单点登录SSO
- For You
- js实现继承的三种方式
- catalan数
- android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
- NYOJ 106 背包问题(贪心,经典题目)
- 在Linux环境下mysql的root密码忘记解决方法 1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。 2.修改MySQL的登录设置: # vi /etc/my.c