引用:http://my.eoe.cn/blue_rain/archive/3631.html

1、一些概念

模式的定义:

每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。

什么是设计模式?

设计模式是在某种特别的情况下,针对某种问题的某种典型、通用的解决方法。

我们是需要适当了解并学习一些设计模式,在程序开发过程中,总是会涉及到一些框架设计,模块设计之类的东西,如果能很好理解并运行设计模式,你所设计的模块或框架将会要稳定得多,因为这些设计模式它们都是通用的解决方案,是经过实践经验了的。

比如说,在程序里,可能会有通知模块,A模块的数据发生变化,B模块需要得到通知,对于这样的需要,你可能会想到用"广播","消息"或者"回调"的方式来解决,的确,刚才我所说的那三种也能解决,但是,这三种都是存在一些缺点,比如说广播,用Intent来传输数据很困难,对于"消息",无法很好的跟踪,对于"回调",有可能你A与B模块根本不可相互访问。此时,如果你会用观察者模式的问题,这种问题可以很轻松解决。

当然,这里是需要具体问题具体分析的,我主要的意思就是说,要适当利用模式,我们不能为了用模式而去用模式,我们是要用模式来解决我们实际的问题。

概念完整性

关于概念完整性,在《人月神话》一书在有大量的阐述,这里,我把我的理解写出来,与大家分享。

1)概念完整性是系统设计中最重要的考虑因素。当你的系统规模越大,这一点体现得越明显。

2)为了获取概念的完整性,设计必须由一个人或者具有共识的小型团队来完成。这一点很好理解,关于设计,可以让所有的人参与,但是决定权在少数人手里,如果大家都想参与设计,这是根本没有办法保正系统设计是统一完整的。

3)要获得概念上的完整性,就必须有人控制这些概念,类似于贵族的专制统治。这里,对于团队中的项目经理或架构师必须对项目有绝对的权威,不然,这个项目里面的就无法统一号令。

4)概念完整性表现有:

1
2
3
4
5
- 开发过程中,需求、设计、编码的一致性
- 整个程序具有统一的风格,比如对话框样式,按钮风格,色调等UI元素
- 整个程序具体统一的结构,比如不同模块访问网络,它们的调用方式一致,例如异步访问都用回调方式通知结果,相同的功能应该提取成共通模块。
- 开发人员能很好的执行需求人员和设计人员的意图。
- 有完整的文档,需求文档,设计文档,测试文档,处理流程的文档等。

如何保持概念完整性

1
2
3
4
5
- 在制度上给予保证,产品的负责人必须建立技术上的绝对权威
- 技术负责人员(SE,SL)必须严格执行项目的需求,设计,必须深入到编码细节
- 在不同阶段,保持与所有人员的持续沟通,鼓励开发人员提意见。
- 让开发人员参与设计,但不决定设计
- 通过持续的反馈和沟通来实现模块重用

2、设计之前应该做什么

2.1 共通类的设计

2.1.1 Widget设计

TextView
EditText
Button
Title bar
Tool bar
...
### 为什么要提供这些共通控件? ###

统一字体大小,如App字体不随系统字体变化而变化
统一UI式样,如Button, EditText具有相同的背景等
复用代码

2.1.2 Adapter Items

根据式样,提取需要在AdapterView中显示的Item
简单的复合布局
自绘制,从而提高滑动性能
- ListView中放Gallery时,提高上下滑动性能
- 尽量优化绘制
### 数据驱动 ###

Adapter Items提供核心的方法
- setData(Object data)
- getData();
Adapter#getView实现更加简单
- 实现简单
- 不会因为UI变化而变化
下面代码示例了Adapter#getView()方法的实现,它返回BookView,BookView提供方法来接收数据,至于BookView的显示,则根据设置的数据来显示,这就是数据驱动UI。

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public View getView(int position, View convertView, ViewGroup parent) { if (null == convertView) {
convertView = new BookView(getContext());
convertView.setLayoutParameter(new AbsListView.LayoutParameter(150, 150));
} Book book = m_bookList.get(position);
BookView bookView = (BookView)convertView;
bookView.setBook(book); return convertView;
}

2.1.3 Dialog

扩展于Dialog类
提供Dialog关闭的事件
Dialog的高度随内容的变化而变化
可以设置按钮的文字,可见性,字体等方法
设置按钮点击事件的listener
要考虑对话框的三个属性:Title, Content area, Action buttons

2.1.4 Utility

-Log
DateFormat
Bitmap
Notification
Shared Preference
Environment
Device
...

2.2 Task管理

线程只是一种机制,保证我们要完成的任务不运行在UI线程(也就是说不阻塞UI),完成的任务才是我们关注的核心,因此,我们可以通过设计,把线程封装,让使用者根本感觉不到是线程,他只用关心他要做的事情就行了。
这里,我们可以设计一种"异步链式调用"的框架,把线程进行了封装。使用都只需要这样用:

1
2
3
4
5
new TaskManager()
.next(task1)
.next(task2)
.next(task3).
.execute();

这里,task1, task2, task3是顺序执行的,举个例子:我们要访问网络,取得一个图片,使用这个TaskManager我们需要3个task,

task1:显示一个ProgressDialog。

task2:访问网络,创建bitmap。

task3:关闭对话框,显示bitmap。

这一点,可以参考CoreLib工程中的task.TaskManager类。

关于TaskManager,有以下几点需要注意:

-封装了线程
让调用者只关注自己的业务处理
保证顺序链式地执行某一个任务
上一个任务的输出,作为下一个任务的输入
能暂停、恢复任何一个任务

2.3 缓存设计

-把内存占用量大的对象存放在缓存中,如bitmap
利用了LruCache类来实现
利用了AsyncTask类来加载bitmap
不用再手动释放bitmap内存,该操作有风险
不用再关心AbsListView的scroll状态
关于缓存的更多详细细节,请参考[ 请参考CoreLib工程中的cache包 ]。

这样做,有什么好处, 不用再手动释放bitmap内在,该操作有风险,因为该bitmap是否有View引用,如果当一个View在试图绘制一个已经回收的bitmap,这里会抛出异常。

2.4 线程管理

无消息循环的线程:

1
2
3
4
5
6
new Thread(null, new Runnable() {
public void run() {
// Do you works.
} }, "Thread_name_xxx").start();

什么情况下使用这种线程:

-做完一件事情就结束,这件事发生频率不高,比如从SD card中读取图片数据
不需要复用线程

在使用线程,最好给线程加上名字,这样利用高度与跟踪。

有消息循环的线程:

这样的线程拥有消息循环,当消息队列中没有消息时,这个线程会被挂起。我们要做一件事情时,只需要给它发送一个消息就行了。

这种情况通常是为了复用线程,不用频繁创建线程,比如音乐播放器程序,专门启动一个有消息循环的线程来获得音乐的专辑图片。

我们通常还要创建一个与这个线程的消息循环(Looper)相关联的Handler,由它来处理消息,注意,这做的事情是运行在后台线程的。

3,程序框架如何设计

Android程序的结构

UI层
数据展示与管理
用户交互
绘制
Adapter
业务逻辑层
持久化数据(内存中,相当于全局数据)
数据加式(数据层的数据有时候需要进行加工成UI层需要的数据)
数据变化的通知机制
数据层
数据访问(DB,文件,网络等)
缓存(图片,文件等)
配置文件(shared perference)

下面,我试着画了一个Android程序的结构,如果有不好的地方,欢迎指正。

4,一些基本原则

下面列出一些通常的原则,我们应当在开发过程中遵循,欢迎补充与指正。

4.1 提供initialize()方法

在Activity.onCreate()或者View的构造方法中调用,在以后看代码时,人们通常首先会去找initialize()这样的方法。

4.2 封装点击事件

把View的点击事件,提成方法,这样在listener处只是一个方法调用者,一般的事件封装为:onXXXClick(View v)。

4.3 设计一个BaseActivity类

让所有的Activity都继承自BaseActivity类,这样,我们可以做很多有用的事情

-定义共通属性
显示共通对话框(Progress dialog)
取得top activity
可以手动管理启动的activity

4.4 设计Application类

存全局数据,比top activity, application context。

4.5 异常处理

-报告功能是处理异常的精髓
在finally块中执行清理操作
不要用try-catch-finally来判断业务逻辑
考虑设计自定义的异常类

4.6 标注的使用

-重写的方法一定要加@Override
不使用的方法,不要删除,可以标记为@Deprecated,这个做法在维护型的项目中特别有用。

4.7 注册与反注册

-局部广播
各种listener
Service等

4.8 封装Bitmap操作

我们应当把Bitmap操作封装起来,比如从文件加载,保存,网络下载,动态计算sample size等。有了封装后,我们可以对其集中优化。

4.9 绘制处理

一定要注意绘制方面的东西,不要在onDraw()/onTouchEvent()中创建新对象。

android 设计的更多相关文章

  1. 【转】Android设计中的.9.png

    来源:http://isux.tencent.com/android-ui-9-png.html Android设计中的.9.png 注意:当使用9.png做TextView背景时,一定要设置内容区域 ...

  2. Android 设计随便说说之简单实践(合理组合)

    上一篇(Android 设计随便说说之简单实践(模块划分))例举了应用商店设计来说明怎么做模块划分.模块划分主要依赖于第一是业务需求,具体是怎么样的业务.应用商店则包括两个业务,就是向用户展示appl ...

  3. Android 设计随便说说之简单实践(模块划分)

    上篇随笔随(Android 设计随便说说)便说了一下什么是设计以及设计的原则,这里举一个简单的例子来进一步的说Android设计.我们以应用商店的设计来举例. 在设计之前,需要把握两部分内容,才能使得 ...

  4. android设计的布局在阿拉伯语下界面错乱的解决方法

    (1)正在AndroidManifest.xml声明文件的application元素中,增加” android:supportsRtl=true” (2)建] androidの设计的布局在阿拉伯语下界 ...

  5. Android设计中的.9.png图片

    .9.png是一种能够自己定义拉伸特定区域的图片格式. 简书:Android设计中的.9.png图片 在Android的UI设计开发中,非常多控件须要适配不同的手机分辨率进行拉伸或者压缩,这样就出现了 ...

  6. android设计准则

    ------------缘由-------------------------------------------------------------------------------------- ...

  7. Android 设计一个菱形形状的Imageview组件.

    网上没有资料,特来请教下大神 Android 设计一个菱形形状的Imageview组件. >> android这个答案描述的挺清楚的:http://www.goodpm.net/postr ...

  8. Android 设计中的.9.png

    在 Android 的设计过程中,为了适配不同的手机分辨率,图片大多需要拉伸或者压缩,这样就出现了可以任意调整大小的一种图片格式“.9.png”.这种图片是用于Android开发的一种特殊的图片格式, ...

  9. android 设计工具栏

    设计工具栏Action Bar(订制工具栏类型) 工具栏给用户提供了一种熟悉和可预测的方式来执行某种动作和操纵应用程序,但是这并不意味着它就需要和其他的应用程序看起来一样的.如果想设计工具栏以使得它能 ...

随机推荐

  1. 真刀真枪压测:基于TCPCopy的仿真压测方案

    郑昀 基于刘勤红和石雍志的实践报告 创建于2015/8/13 最后更新于2015/8/19 关键词:压测.TCPCopy.仿真测试.实时拷贝流量 本文档适用人员:技术人员 提纲: 为什么要做仿真测试 ...

  2. ZeroMQ接口函数之 :zmq_plain - 明文认证

    ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_plain zmq_plain(7) ØMQ Manual - ØMQ/4.1.0 Name zmq_plain  ...

  3. mac java环境变量设置

    Mac下添加java环境变量 方法一:全局配置   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #临时提权   sudo su   #输入密码   vi /et ...

  4. Unity3D设计原则

    原则1:单一职责 原则2:里氏替换原则(子类扩展但不改变父类功能) 原则3:依赖倒置原则 原则4:接口隔离原则 原则5:迪米特法则(最少知道原则) 原则6:开闭原则 原则1:单一职责原则 说到单一职责 ...

  5. Socket通讯实例-基本Socket

    转自:http://www.cnblogs.com/mahaisong/archive/2011/07/25/2116475.html (讲的很好,很细) 参考:http://blog.sina.co ...

  6. myString操作符重载

    写在前面的话: 重载是C++的重要内容,在自定义一个类的时候,需要对类中的方法进行重载,才能方便的实现相应的功能,比如一些运算符,构造,析构函数,一些功能函数等等,而C++语言自带的这些东西只使用于基 ...

  7. POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24081   Accepted: 106 ...

  8. Tomcat学习记录

    阅读摘录如下: 本质 Tomcat最本质就是个能运行JSP/Servlet的Web服务器 , 因此最典型的应用就是用户通过浏览器访问服务器,Tomcat接收到请求后转发给Servlet,由Servle ...

  9. PHP 使用 debug_print_backtrace() 或 debug_backtrace() 打印栈轨迹

    <?php /* 使用debug_print_backtrace() 或 debug_backtrace() 打印栈轨迹 */ function fun1() { print "Hel ...

  10. GET,POST — 简述

    本文主要对GET与POST基本区别进行汇总并掌握,如有错误与遗漏之处,请指出. 文章出处:http://www.cnblogs.com/useryangtao/ 1. HTTP HTTP(即超文本传输 ...