Android remote debug

上周学习了JPDA里关于JVMTI的基本知识,然后动手写了一个简单的Agent实现。刚好最近看到美团技术博客里,关于Android远程调试的一篇文章。https://tech.meituan.com/2017/07/20/android-remote-debug.html 于是动手写了一下。 注: 本文大部分内容,和美团的这篇技术博客相似,可以理解为根据美团的文章进行实践,然后记录笔记,以及附加一些我在实践过程中遇到的一些问题。

0x0 背景

身为一个Android开发者,肯定遇到过很多线上问题无法复现,难以排查的情况。有时候因为没有线上问题对应的机型,另外有些时候,即便是机型一样,也很难模拟用户使用时的具体情景,导致问题迟迟无法解决。 而我们开发过程中,遇到绝大部分问题,除了尝试复现,还可以结合Debug等手段,获取当前程序运行的状态,包括变量信息、堆栈信息、线程信息等等。这个时候我们就在想,如果可以远程调试就好了。 而我们知道,Java程序时支持远程调试的,那Android是不是也一样呢?答案是肯定的。

Android虽然采用了Dalvik以及ART模式来适配手机,但本质还是一种特殊的JVM, 之前介绍JPDA的时候已经介绍了JVM调试框架。要想让JVM支持调试,那么必须在JVM启动的时候加载支持JVMTIAgent,通过这个AgentJVMTI通信,设置断点、获取堆栈信息等。Hotspot VM以及Dalvik VM都自带了JVMTIJDWP实现。即我们可以用任意我们喜欢的JDI去进行调试,例如IDE自带的调试工具,或者jdb, 甚至自己动手写一个JDI工具来调试。

0x1 Android调试原理

在一般的Java程序中,要支持调试,必须(排除自己实现JDWP的情况)使用如下命令来启动Java程序:

java -jar ${jarName} -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 

启动之后,就可以用各种调试工具通过ip:port连接到该程序上去进行调试(根据transport不同,连接方式会有区别)。 而开发Android程序的时候,要想让Android程序支持调试,通常来讲,会有如下两种方式:

    1. 需要将Continue Reading →

Play with JVMTI

上周讲了如何使用 Android Studio 来进行高阶调试。今天来讲一讲关于 Java 调试背后的东西————JPDA.

0x0 JPDA

Java Platform Debugger Architecture,简称JPDA,是Java平台针对调试(Debug)一套完整的架构定义。它定义了底层后端接口JVMTI、中间的传输层JDWP,以及顶层前端的调试接口JDI,一共三层结构。

 Components Debugger Interfaces / |--------------| / | VM | debuggee ----( |--------------| <------- JVM TI - Java VM Tool Interface \ | back-end | \ |--------------| / | comm channel -( | <--------------- JDWP - Java Debug Wire Protocol \ | |--------------| | front-end | |--------------| <------- JDI - Java Debug Interface | UI | |--------------| 
  • JVMTIJava Virtual Machine Tool Interface

Debug with Android Studio

使用调试工具(Debug Tools)进行调试(Debug)是一个程序员必不可少的技能,但是很多程序员对于调试工具的使用,很多都仍处于初级阶段。即便是工作很多年的老鸟,可能也只会最基础的调试。前段时间根据自己所掌握的调试基础,给公司内部作了一个分享,这里再行记录一下。 其实从准备开始记录这些基础的琐碎的东西,经常要拖好久才能完成。一个是因为有些忙,一个是因为有些懒,还有一个是因为觉得,所要记录的这些东西太基础了。 技术的学习就是这样,有些东西,无论基础与否,如果不熟悉,或者好久没有使用了,便生疏了。而一旦掌握或者重新掌握,觉得不过如此而已。
所谓不积跬步无以至千里,不积小流无以成江海。还是踏踏实实的记录下来吧,权当以后做一个回顾。

0x0 基础信息界面介绍

  • 首先上来介绍一下最基本的信息——图形界面介绍。

主界面一览图

如图所示,我将界面分成了ABCEDF六个区块,其中A为我们最常用的代码工作区,B为断点调试的快捷按钮区(Step Out/Step into等等),C为Debug相关工具快捷按钮区(Restart/Resume/Stop等等),D为当前断点线程和方法栈展示区,E为变量展示区,F为断点信息区。

:Intellij和Android Studio,以及不同版本的Android Studio之间界面会有些许差别。本例中版本为Android Studio 3.3.

  • B-调试快捷按钮区域

调试快捷按钮区域

第一个按钮的作用是快速定位到当前断点(指的是当前运行)所在位置。当我们调试到某行代码时,往往会点击某个类或者某个方法去查看它的源码(不是Step Into,只是查看代码),点了好几层之后,想要快速回到最开始的位置,只需要点击这个按钮即可。 接下来的4个按钮做过研发的同学想必都很熟悉了,分别是Step Over/Step Into/Force Step Into/Step OutStep IntoForce Step Into的区别在于,前者能够进入自己编写以及第三方库(包括Android SDK)的方法(默认跳过jdk的方法),后者可以进入jdk源码的代码。 第5个按钮是Drop Frame,顾名思义,是将当前帧卸载掉,意思就是讲当前执行的代码回滚。为什么这个按钮在这里是灰的,不可点击的呢?因为Android的Dalvik虚拟机及ART机制都不支持该操作,如果我们是原始的Java程序,jvm支持的情况下,就可以实现这个功能。 我们可以在junit中试一下这个功能。

Drop Frame

Drop Frame后面是Evaluate Expression按钮,这个也是非常有用的一个功能。点击这个按钮,我们可以编写代码做一些计算工作。

Evaluate Expression

最后一个置灰的按钮是Trace Current Stream Chain,是用来跟踪java8lambda语法流状态的。这里不展开讲解。

  • C-调试相关工具快捷按钮区 这一块蛮简单的,主要是上面提到的中断调试、恢复运行、查看设置断点,以及一些调试设置等。大家可以自行试用一下。 主要提一点就是照相机📷那个按钮,Get the thread dump,可以将线程信息导出来查看。

线程信息

... Continue Reading →

Maven Publishing

Upgrade gradle to 4.6 (1)

下载了最新版的Android Studio之后,gradle插件版本可以升级到3.2.0,对应gradle-wrapper版本升级到4.6,与此同时,项目中一些自定义任务需要进行相关的修改,记录一下。

0x0 Legacy publishing

我们编写的自定义库,很多时候需要发布到maven仓库去供自己的其他工程通过maven依赖,或者供第三方直接依赖使用。通过仓库管理,可以节省掉很多文件备份、拷贝过程,也减少了之间错误发生的可能性。以及,如我上一篇文章提到的混淆,可以通过自身工程配置consumerProguardFile来配置混淆,不需要其他地方再单独配置。

在以前的gradle版本(我们以前用的是2.3.3),可以用maven插件的uploadArchives来发布依赖包。

afterEvaluate { project -> signing { required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } sign configurations.archives } uploadArchives { configuration = configurations.archives repositories.mavenDeployer { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: getRepositoryUrl()) { authentication( userName: getRepositoryUsername(), password: getRepositoryPassword()) } pom.project { name POM_NAME artifactId POM_ARTIFACT_ID packaging POM_PACKAGING description POM_DESCRIPTION url getRepositoryUrl() } } } } 

在升级到新版本之后,uploadArchives任务失效了。 在之前的版本时,通过uploadArchives上传仓库时,gradle的输出是这样的:

> Task :lib:uploadArchives Uploading: com/xxx/2.0.1-SNAPSHOT/maven-metadata.xml to repository remote at https://------.com/repository/maven-snapshots/ Transferring 0K from remote Uploaded 0K...               
                     
                Continue Reading →       
            

Upgrade to gradle

Upgrade gradle to 4.6 (0)

下载了最新版的Android Studio之后,gradle插件版本可以升级到3.2.0,对应gradle-wrapper版本升级到4.6,与此同时,项目中一些自定义任务需要进行相关的修改,记录一下。

0x0 自定义混淆

在Android Studio里开发apk定义混淆很简单,只要在相应地方里配置proguardFile或者proguardFiles即可。如果是library模块供application依赖(project依赖或者aar依赖),可以在library里配置consumerProguardFile就可以自己控制混淆配置,无需在application层配置。而如果是library模块,输出jar包供第三方使用,则需要自己进行混淆。混淆可以直接使用proguard工具进行混淆,当然更方便的是使用Gradle自带的ProguardTask来进行混淆。

在之前版本的gradle环境(gradle 3.0.1)中,我们的配置如下:

 1 task("proguard${nameCap}Jar", type: ProGuardTask, dependsOn: ["make${nameCap}Jar"]) { 2 group = 'jar' 3 description = 'make proguard jar' 4 5 injars originalJarPath 6 outjars proguardJarPath 7 configuration 'proguardContinue Reading →       
            

Gradle incremental build on Android Studio

最近在折腾Android Studio打包优化,其中有些地方使用了gradle的incremental build增量构建。不是特别顺利,因此想把相关心得记录下来,当做一个笔记。

0x0 前言

谈起增量编译,Android开发者一定都不陌生。自从谷歌官方开始停止eclipse插件ADT开发和维护之后,相信大家都已经转战到Android Studio上来了。当我们自己使用Android Studio编译运行apk的时候,经常可以看到gradle console里打印的:xxxxx:build UP-TO-DATE,这个便是增量构建。增量构建可以跳过很多不必要的重复编译构建,为我们节省下大量的时间。
而在开发Android程序的时候,我们经常会遇到,需要使用gradle task手动编写一些gradle脚本,来辅助打包,或者做一些资源处理。 当然,也有很多task是继承gradle原生的task来实现的。gradle的大部分task,已经默认支持增量构建,无需我们作任何处理。这里讲介绍如何编写一个自定义的task,使其能够支持增量构建。

0x1 需求

这里我们举一个简单的例子,我们有若干个资源文件:a.txt, b.txt, c.txt....,存放在app/data/下面,这些文件中都有一个version=@@VERSION_CODE@@的内容。我们希望每次构建的时候,能够自动将版本号统一修改,放到assets目录下去。

0x2 实现

首先我们创建一个自定义任务,让打包任务依赖于其执行:

task processAssets { ... } tasks.assemble.dependensOn processAssets 

这个例子,其实可以用继承Copy来实现。我们可以如下实现

def version = "1000" task processAssets(type: Copy) { group "custom" println("processAssets") from("data") { include Continue Reading →       
            

Retrofit 2.0 源码阅读解析

前言

Retrofit是服务于Java/Android的网络请求框架,之前已经在很多项目中使用该框架来进行网络请求,然而一直没有深入去阅读它的源码,近期大致翻看了一下,在这里作一个简单的总结。

Retrofit主要实现了如下功能:

  1. 按照Restful协议实现框架;
  2. 根据注解配置访问方法、路径及参数,使代码具有更高的可读性;
  3. 使用接口访问网络接口,完全无需关心内部实现;
  4. 抽象和实现解耦,通过自定义接口转化器和数据格式转化器,来实现自定义配置;

准备工作

第一步:准备一杯咖啡或者一杯茶,然后可以适当准备纸笔用来记录(也可以直接在电脑上用文档记录)

第二步:开始从github上下载Retrofit的源码,地址如下:https://github.com/square/retrofit.

第三步:使用任何自己喜欢的IDE或者文本编辑器打开,我用的是Sublime Text.

开始分析源码

下载完源码之后,我们发现整个目录下有若干个子目录及文件:

|- retrofit
    |- retrofit
    |- retrofit-adapters
    |- retrofit-converters
    |- retrofit-mock
    |- samples
    |- website
    |- other files…

其中,retrofit目录下为整个框架的基础代码;retrofit-adapters目录下为接口适配器代码,它的作用是实现将实际网络实现接口,转化为你编写的应用接口(例如Java8语法、RxJava接口等);retrofit-converters是数据格式转化器,负责将网络流数据转化为你想要的目标格式(ProtobufGson等);retrofit-mock则是一个虚拟Web Server,用来进行虚拟网络访问测试;samples顾名思义,是例子代码;websites则是用来部署在github io上的静态网站代码;其余文件这里不过多赘述。

下面将根据retrofit官网GitHubServicelistRepos例子来一步步深入解读源码:

// Create Java API public interface GitHubService { @GET("users/{user}/repos") Call<List<RepoContinue Reading →       
            

Singleton Pattern and Java memory model

前言

单例模式可以说是设计模式里最常用、也是最容易手写的案例了,然而要真正把单例模式写好,并明白为何那么写,还是蛮有文章的。最近在温习Java内存模型相关知识,准备就单例模式的一些特殊写法,来谈一谈Java Memory Model.

单例模式的常见写法

  • Case 0.

静态常量对象、静态内部类、枚举类型写法。 这三种写法都是线程安全的,在本文中并不展开讲解。这三种写法不能使用动态参数创建实例,使用场景也相对有限。

  • Case 1.
public class SingletonTest { private static SingletonTest sInstance; public static SingletonTest getInstance() { if (sInstance == null) { sInstance = new SingletonTest(); } return sInstance; } public static void main(String[] args) { SingletonTest.getInstance();...               
                     
                Continue Reading →       
            

build variants on android studio

Foreword

Android studio作为google官方推荐的Android开发IDE,的确是一个很棒的开发工具,虽然它曾经那么难用不堪,不过成长下来,已然能够完全取代eclipse成为Android程序员们最应该使用的开发工具。Gradle工程对于打包环境配置能够让你从冗余的xml配置中解放出来,在这里我讲介绍一下Android Studio的gradle中的build variant相关的一些小知识。

Android的build variant主要由build types和product flavors做笛卡尔乘积得到的集合(主要的意思是还会有其他一些比如针对cpu架构的,在此不做详细介绍).

Build types

Android Studio默认有两个build type类型,releasedebug,以下是他们之间的一些区别:

  • 1: 在debug类型中,debuggable被默认置为true, 而在release中默认是false, 该值在生成项目(build project)时,会和BuildConfig.DEBUG字段对应,通过它我们可以做一些逻辑处理。
  • 2: debug类型默认使用debug签名,而在release中,你必须手动指定一个签名。更多关于签名的信息,请点击这里

我们还可以添加自定义的build type,需要注意的是其名字不能和渠道名(product flavor)相同。在自定义的build type中,我们需要根据自己的需求设置对应的属性。例如

manifestPlaceholders = [INSTALLED_CHANNEL: "default_channel"] debuggable true versionNameSuffix ".alpha" // 开启混淆 minifyEnabled true zipAlignEnabled true // 移除无用的资源文件 shrinkResources true proguardFiles 'proguard-rules.pro' // 签名设置 signingConfig signingConfigs.release 

等等,以及其他一些属性。

在第一点我们提到可以通过BuildConfig.DEBUG来在java代码中写一些逻辑,比如我们要在开发过程中输出程序调试日志,而在正式发布的包里面把这些日志去掉。我们可以这么做:

if(BuildConfig.DEBUG) { Log.d("Test", "hello, this is a debug log"Continue Reading →       
            

FixedAspectRatioView

Foreword

在Android开发过程中,我们可能有需求需要将一个View对象固定为指定比例,比如4:3, 1:1之类的。一般的做法有两种,一个是预先知道宽高的值,直接在xml中给出指定的dp值,这种做法有个缺点,就是每个单独的视图都必须给定值,而对于我们并不知道宽或者高的具体值时,便很难做到。

例如一般情况下,我们希望宽等于(或者接近,因为可能会有padding)屏幕宽度,而高度根据给定的比例缩放。

所以第二种做法便是根据当前的宽/高值,根据给定的比例值动态计算另一个值。

Realization

在Android中,我们可以重写onMeasure方法来重新计算宽高值,系统在布局的时候会根据相应的计算结果来重新计算,然后给视图分配出指定的宽高。

一般情况下,我们希望在xml中指定宽高比例,以及基准的边(即宽不变,高对应重新计算;或者高不变,宽重新计算)。因此,我们需要在style中声明指定的style,在xml中设置对应的值,在View的构造函数中获取指定的值,然后在onMeasure方法中计算。

下面我们按照这个步骤来写出一个自定义的FrameLayout (你可以实现自定义的各种View,比如RelativeLayout,或者ImageView,我个人的建议是自定义ViewGroup类型,推荐FrameLayout或者RelativeLayout, 这样该控件之内的其他控件都会固定在这个范围之内,同时在其他地方使用时也可直接使用)

  • 1.声明自定义style 新建一个style_ratio_view.xml文件,或者其他名字,也可以直接放在style.xml中,内容如下。

     <declare-styleable name="FixedAspectRatioView"> <attr name="aspectRatioWidth" format="integer" /> <attr name="aspectRatioHeight" format="integer" /> <attr name="fixedAspect" format="enum"> <enum name="width" value="0"/> <enum name="height" value="1"/> </attr> </declare-styleable> 

    其中fixedAspect是一个枚举类型,标识需要固定的边。而其余两个是整型类型值,标识宽高比。

  • 2.编写FixedAspectRatioView 新建一个类,继承自FrameLayout,代码如下:

    Continue Reading →

Android Network Frameworks

TODO

android网络库调研
1、基础功能特点
2、并发数,并发时效率(不同并发数效率,响应时间)
3、内存使用;
4、不同场景使用情况(图片请求为主,数据请求为主等)
5、基础参数(包大小,更新情况,版本兼容情况)

HttpClient, HttpUrlConnection and OkHttp

Before Android Gingerbread(2.3) HttpUrlConnection is not stable cause it has some un-fixed bugs. So HttpClient is recommended as default. Since Gingerbread, the bugs are fixed, and HttpUrlConnection is more lightweight and more easy to maintain.

Both HttpClient and HttpUrlConnection are developed based on HTTP, when OkHttp based on HTTP and SPDY. That is said, OkHttp would be quicker and more efficiently.

AsyncTask

  • Cancelable false
  • Support network change false
  • Parallel work support: not simple
  • May lead... Continue Reading →

Using Annotation

Foreword

Annotation(注解)是从Java 1.5开始新加的特性,距今已经好多年的历史了。不得不说注解是一个很好用的东西。不过本文不打算深入解释Annotation,而是准备从Android提供的Annotation来讲述其使用技巧。

Why Annotation

在开发过程中,我们会遇到各种设计接口、方法时,需要对方法的参数进行限制,来避免或者尽量避免由于开发人员的错误调用而导致程序运行不正常乃至崩溃。 例如:我们常用的TextViewsetText方法有多个重载实现,而我们常用的为:

public final void setText(CharSequence text) { setText(text, mBufferType); } public final void setText(int resid) { setText(getContext().getResources().getText(resid)); } 

这两个方法。当我们从网络流(或者其他一些场景下)获取到数据,直接调用setText方法,经常会出现传入错误的int类型值,这个int类型值并不是正确的R.string.*值,在程序运行的时候就会报错,导致程序崩溃(Force close)。

在没有注解的情况下,我们是很难做出判断,这些操作只能凭开发人员的细心判断达到。但是人往往是会犯错的,尤其是多人协作的时候,这种问题尤其容易出现。而在Annotation的帮助下,我们可以很好的实现控制,让编译器去协助我们完成检查,在编译时便检查出错误。

注意:这个错误只能在视觉上呈现,实际编译仍能通过。

How to use Annotation

针对上述场景,Android的support-annotation包里提供了StringRes这个Annotation,在设置了@StringRes注解的参数PARAMETER, 使用非R.string.*类型的int值是,便会报错: Error

注:本文的IDE为Android Studio, 并未测试Eclipse上的显示和提示.

查看StringRes的源码实现如下:

... Continue Reading →

Basic Transition on Android Lolipop

Foreword

好久没有写博客了,究其原因是好久没有好好学习,没有好好深入研究代码的实现云云。拖延症云云屁话不提。 Android Lolipop出来有一阵了,不能老啃着targetSdkVersion=14, minSdkVersion=9过一辈子吧,不然又有一股兼容IE6既视感。 本来是准备用英文写的,出于很多稀奇古怪的原因(譬如说用老外的语言把老外做的东西转述一遍,总有点做无用功并且显摆的感觉,而且可能还语病百出)不提,还是踏踏实实用中文吧。用什么语言是其次的,内容才是关键。

Scene Animation

Android介绍一共有三种Animation,分别是:

  • Property Animation
  • View Animation
  • Drawable Animation

Property Animation 属性动画的从HoneyComb 3.0(Api Level 11)开始支持,主要特征为实时改变对象的属性来达到动画效果,比如一个移动动画,动画的过程中物体的坐标即其当时的坐标,和现实世界的移动动画一样。

View Animation则不然,View Animation视图动画,只是绘制出动画过程中物体所在的位置,而物体的实际坐标并没有发生改变。这一点在我们点击移动过程中的物体便可以发现差异:当物体A 从 X 点通过动画移动到 Y 点时,其物理位置仍然处于 X 点,和 所见即所得 相违背。

Drawable Animation绘图动画允许你加载组图片资源来构建一个动画,即逐帧动画。逐帧动画是最传统最古老的动画实现方式了。

Scene Animation (场景动画)其实并不是一个严格意义上的动画机制,只是一个动画表现形式。即从场景 A 变化到场景 B 时所呈现出来的动画效果。其底层实现是通过 Animator,即Property Animation实现的。 本文标题写的是BasicTransiton on Lilitop,事实上在4.0Kitkat的时候就已经支持该动画了。

Animation Effect

Realization

初看这个效果,按照以前的实现方式,移动的整个部分只有一个静态布局。在点击各个 RadioButton 之后启动一个 translate 的动画,改变三个按钮的坐标或大小达到新的布局效果。使用Property Animation实时改变或者使用View Animation绘制动画完成之后重设坐标。实现起来并不难,缺点是需要针对每一个元素单独设置动画,会有一系列坐标和形状计算等繁琐操作。

视屏中从场景1切换到场景2时,三个元素发生了位置移动,我们会按照如下步骤来实现:

  • 1:为各元素定义动画的xml文件,动画类型为translate
  • 2:通过AnimationUtil为各元素分别加载对应的Animation实例
  • 3:调用各元素的startAnimation方法

或者:

  • 1:使用一个共有的ValueAnimator计算动画系数
  • 2:在ValueAnimator的回调方法中动态计算并设置各元素的坐标
  • ... Continue Reading →

Respiration lamp animation

Foreword

I am developing an android application, in which I want to show a circle which flashes like a respiration lamp. Here I am going to use view animation to realize it.

Implementation

To accomplish this, we have five steps:

  • 1: create an android application.
  • 2: create a layout xml file for view inflation, and a anim xml file with animation details. (Also you could hard code the animation info, but it’s not recommended cause it is difficult to refactoring.)
  • 3: add an ImageView to the layout xml
  • 4: create an activity to show the view
  • 5:... Continue Reading →

Mediator

Introduction

Object oriented programming allows us to define a lot of classes which are regarded as an encapsulated object. A perfect object knows only what it can do, what it needs, but never knows who uses it. And what’s more, when it cannot do something, the object would use other objects to accomplish the task when it doesn’t know the details of the other objects. That is, the relationship between the objects.

Usually our system would be very large and complex, and we defined lots of classes, there would be many connections between them, in the worst case, every... Continue Reading →

Iterator

Introduction

One of the most common data structures in software development is what is generic called a collection. A collection is just a grouping of some objects. They can have the same type or they can be all casted to a base type like object. A collection can bes a list, an array, a tree and the examples can continue.

What is important is that the collection provides a way to access its elements without expose their internal structure. So that, we shoud hava a mechanism to traverse a list or an array in the same way, when it... Continue Reading →

Interpreter

Introduction

The interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. If a particular kind of problems occurs often enough, it might be worthwhile to express instances of the problem as sentences in a simple language. We can build an interpreter that solves the problem by interpreting these sentences.

Definition

Given a language, define a representation for its grammer along with an interpreter that uses the representation to interpret sentences in the language.

UML class diagram

Interpreter Pattern

Participants

Command

Introduction

Sometimes it’s necessary to issue requests to objects without knowing anything about the operation being requested or the receiver of the request.

For example, when you’re designing an user interface toolkit, include objects like buttons and menus that carry out a request in response to user input, but you don’t know and you can’t implement the request explicitly in the button or menu because only applications that use the toolkit know what should be done on which object.

The Command pattern lets toolkit make requests of unspecified application objects by turning the request itself into an object, which... Continue Reading →

Chain of Responsibility

Introduction

In object oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

For instance, in Android development, touch event and click event you attach to a control, the event would be dispatched top-down from ViewParent to its subviews, like ViewGroup or ImageView… Each... Continue Reading →

Proxy

Introduction

When you want to use a large object in memory, a file or some other resource that is impossible or expensive to duplicate, but you do not want to instantiate it or copy it right now cause you only need a portion information of it, you can use Proxy pattern. A proxy supplies an interface for you to do most operation of the original one, the proxy will forward them to the original object. Proxy is well known in reference counting pointer object.

Definition

Provide a supporgate or placeholder for another object to control access to it.

Continue Reading →

Flyweight

Introduction

When you want to deal with a large number of objects, most of which are common (or you can find their common parts), you may find that the storage costs too much. Flyweight pattern can help to reduce the number of objects, or reduce the storage cost by sharing their intrinsic.

For instance, if I have a lot of messages, and I want to send them to many people by SMS, I have stored the contacts in a XML file like:

<?xml version="1.0" encoding="UTF-8"?>
<Contacts>
    <Contact>
        <Name>Tom</Name>
        <Mobile>+11-12345678</Mobile>
        <Email>tom@gmail.com</Email>
    </Contact>
    <Contact>
        <Name>Jack</Name>
        <Mobile>+11-12345699</Mobile>
        <Email>jack@gmail.com</Email>
    </Contact>
    <Contact>
        <Name>Christina</Name>
        <Mobile>+11-12225699</Mobile>
        <Email>christina@gmail.com</Email>
    </Contact>
    <!--
    	more contacts ...
	-->
</Contacts>

And the messages are like:

Continue Reading →

Facade

Introduction

When you design a system into subsystems to reduce complexity, you want to minimize the communication and dependencies between the subsystems. You may want to have a single simplified interface to help to achieve this. Here comes the Facade pattern.

Definition

Provide a unified interface to a set of interfaces of subsystems. Facade defines a higher-level interface that makes the subsystems easier to use.

Diagram

Facade

Participants

  • Facade
    • knows which subsystem classes are responsible for a request.
    • delegates client request to appropriate subsystem objects.
  • subsystem classes

Decorator

Introduction

Sometimes you may want to add some responsibilities to your object dynamically and transparently as decorations, and they can be withdrawn at anytime. One solution is to implement subclasses to support each combination, but that’s not a good idea, cause you would produce an explosion of subclasses, Or the class definition maybe hidden or otherwise unavaliable for subclassing. Decorator pattern is designed to solve this problem.

Definition

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

UML class diagram

Decorator pattern

Participants

... Continue Reading →

Some Questions

Foreword

I cannot remember everything I met, so I am gonna write this blog to record them.

Question

When you have three buckets, one is full of apples, one is full of oranges, and the third is full of oranges + apples, each bucket has a label on them, but the the labels are not in their correct position. If you have only one chance to choose one bucket and get a fruit from it, how can you figure them out.

Answer

This is a logic question, and the key of this question is that Both the... Continue Reading →

Composite

Introduction

There must be some times you want deal with tree-structed data, and you always have to discriminate between a leaf-node and a branch. This makes code more complex, and therefore, error prone.In OOP, a composite is an object designed as a composition of one-or-more similar objects, all exhibiting similar functionality. Composite pattern is know as a “has-a” relationship between objects. By grouping them as a group, you only need call one method, operations will perform on all composite objects.

Definition

Composite objects into tree structures to represent part-whole hierarchies. Composite lets client treat individual objects and composition... Continue Reading →

Dive into String

Introduction

String is a final class inheritanced from java.lang.Object, it represents for character strings. All string literals we see in Java, such as “abc”, are implemented as instances of this class.

According to the document, Strings are defined as constants, that means the value of them cannot be changed after they are created. If you want mutable strings, you should use StringBuilder(or StringBuffer).

As a result that String objects are immutable, the can be shared. For instance:

String str = "abc";

is equivalent to:

char data[] = {'a', 'b', 'c'};
String str = new String(data);

String class has two attributes, value and hash.

Continue Reading →

Bridge

Introduction

Bridge pattern is a structural pattern, which is always used to decouple abstraction from its implementation.

Let’s go through the motivation in <<Design Patterns>> :

When abstraction can have one of serveral possible implementations, the usual way to accomodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach is not always flexible enough. Inheritance binds an implementation to the abstraction permanently, which make it difficult to modify, extend, and reuse abstraction and implementations independently.

Well, Here is an example help... Continue Reading →

Adapter

Introduction

When you have two or more interfaces, one of which is incompatible for your needs, you need to modify it. But usually it’s prohibitive to modify the original code, a better way is to use a wrapper to translate the interface to the compatible one. The Adapter pattern will meet your need. For instance, if you have a interface DateUtil#getDate which returns the current date as the “YYYYMMDD”, but actually you need another format like “MM/DD/YYYY”, and it’s impossible or too expensive to modify the DateUtil class. You may write a new class as a wrapper, which we call it adapter to translate it.

Continue Reading →

Dive into clone

Cloning in Java

There must be a lot times that you want to copy an object, or sometimes it’s prohibitively expensive to instantiate new instance. Simply, if you just assign an object to another variable, like:

MyObject obj1 = new MyObject(); MyObject obj2 = obj1; 

But absolutely it is not copy, obj2 and obj1 are different references of the MyObject type object in memory. If you do some change to obj1, it will reflect in obj2. Obviously, this is... Continue Reading →

Prototype

Introduction

Sometimes we would want to clone a object rather than instantiate a new instance, we would use Prototype pattern. Prototype is used to:

  • avoid subclasses of an object creator in the client application, like the Abstract Factory pattern does.
  • avoid the inherent cost of creating a new object in the standard way(e.g., using the ‘new’ keyword) when it is prohibitively expensive for a given application.

To implement the pattern in Java, we need to implement the interface Cloneable. Cloneable is an empty interface, so you could implement an method with any... Continue Reading →

Singleton

Introduction

In software engineering, when develop a software, sometimes you may want to instantiate an object just one time, and keep it all the time with only one instance. To ensure that there is only one instance and that the instance is easily accesible, you should use Singleton pattern.

Definition

Ensure a class only has one instance, and provide a global point of access to it.

UML class diagram

Singleton pattern

Participants

  • Singleton
    • defines an instance operation that lets clients access its unique instance.
    • responsible for creating and maintaining... Continue Reading →

Builder

Introduction

Builder pattern is used to isolate the code from the construction and representation. Unlike Abstract Factory pattern and Factory Method pattern whose intention is to enable polymorphism, the intention of Builder pattern is to find a solution to telescoping constructor anti-pattern.

Definition

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

UML class Diagram

Builder pattern

Participants

  • Builder
    • specifies an abstract interface for creating parts of Product object.
  • ConcreteBuilder... Continue Reading →

Abstract Factory

Introduction

Well, before we start to talk about the intent of Abstract Factory, think about that:

    1. I want to send some message to my customers, but I don’t know (or I don’t care) what kind of ConcreteSender to use.
    1. If I have a new kind of ConcreteSender (e.g. WechatSender), I can add it to my program without modify the exists Factory class.
    1. ….

If we want to use Factory Method, we’ll find that we should do the steps:

Factory Method

Introduction

The Factory Method is a pattern intented to help assign responsibility for creation. It’s an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects(products) without specifying the extract class of object that will be created.

The Factory Method may be used when:

  • The creation of an object makes reuse impossible without significant duplication of code.
  • The creation of an object requires access of information or resources that should not be contained within the composing class.
  • The lifetime management of the generated objects must be centralized to ensure the... Continue Reading →

jekyll-installation

#Foreword

Well, I’m just moving my blog from wordpress to github these days. Jekyll is recommended as the static page generator which is also github-pages’ generator. My home page was cloned from Jekyll-Bootstrap, to be honest, it’s a well-designed template to build jekyll site.

#Installation

  • My operation system: Microsoft Windows 7, 32bit.

Install Ruby

Well, I really like Linux or Mac(I still do not have enough money to buy one.) which support commad-line installation. To install ruby you should download two file from Click here.

  • Ruby
  • Ruby development kit.

Get more information on... Continue Reading →

android note

Custom Theme Style

It’s quite easy for developers to define their own theme by declaring styles in styles.xml file.
like:

<style name="AppBaseTheme" parent="@android:style/Theme.Holo.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> 

~I’ve got a mistake that I copied the code from somewhere which the parent is not right. Wrap you head that parent="android.Theme.Holo" is not right. If you want to use the pre-defined theme, make sure that the... Continue Reading →

Something about jaskson

There are a lot of blogs telling you how to use jackson in your java project, so I am not going to repeat it, just google it yourself.

What I’m going to introduce here is that I’ve got an error when user jackson with boolean value.

When I was using jaskson to parse a Json string value in which there is a boolean value to a java POJO, I’ve got an error like:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "isBoy" (Continue Reading →       
            

unity3d学习问题总结

前言:

学习的时候总会碰到各种问题,经常就是各种搜索、看文档甚至问别人什么的来解决。运气好的时候马上就能搞定,运气不好的时候一个问题得纠结两三天。还有时候甚至是同样的问题第二次还得纠结两三天,细想想来自己没有好好做总结没有记录是导致这种情况发生的罪魁祸首。

那么,是该写一篇博客来总结了。每次碰到问题就在这里加上,解决了就在问题后面附上解决方案,这样子之后如果在遇到找起来就方便多了。


Problem:

1:The animation state *** could not be played because it couldn’t be found!

这个问题困扰我两天了,官方文档以及教程看了半天没找到答案,然后自己瞎琢磨也没整明白。一直以为是代码或者某个地方设置的问题。好吧承认自己愚昧,居然没有去用搜索引擎搜索。今天才百度了一下,在某君的百度空间里找到解决方案。

Solution:

原因是在导入模型动画的时候没有设置导入选项,在Rig选项中应该将Animation Type设置为Legacy(事实上Unity3d的warning中就提到动画片段不是Legacy,我却一直无视这warning……),然后下面的Generation选择合适的,我选的是Store In Root(New)这个。

改完之后Apply一下。重新运行,OK.

原文链接:http://hi.baidu.com/next2_me/item/af74cf873eeab0c098255fc8


Problem:

2:Unity3D生成Android程序安装完后再安卓环境中渲染不完全、闪烁以及有重影问题

这个问题当时也困扰了我几天,一直以为是代码的问题,但是只有几行代码,是不会涉及到渲染优化等问题的。而u3d自带的angrybots以及网上下的一些demo却没有问题。我自己开始写的两个小应用,一个在同学的三星手机上运行没有问题,一个渲染不完全,而在我自己的小米手机1S青春版(我一直管它叫小米手机1s屌丝版)上运行,不仅渲染不完全,还有重影闪烁,体验相当糟糕。

Solution:

在File-Build Settings-PlayerSettings-Resolution and Presentation里取消Use-32-bit-Display-Buffer的勾,选上Use-24-bit-Depth-Buffer,然后在Other Settings里将Graphics Level选用OpenGL ES 1.x

现在市面上安卓手机鱼龙混杂,设备良莠不齐(也不得不吐槽小米自己所谓的牛逼其实隐藏了很多未知的弊端,毕竟一分钱一分货了),真是个很蛋疼的问题。

找到的百度文库原文链接:http://wenku.baidu.com/view/8140d30a59eef8c75fbfb33f.html


##

Problem:

3:Unity3D在Android平台下无阴影效果

这个问题是Unity3D本身的原因,在standalone里可以正常显示阴影,但是在android平台下不行。也不算问题,不过当时不知道困扰了一会。

Solution:

尚未解决,应该是有其他方案来实现实时阴影特效的,如果是静止的就用lightmapping烘焙(虽然我还不知道这个怎么用)。


##

Problem:

4:Unity3D自带的character controller针对碰撞检测OnCollisionEnter的问题

在Unity3D中人物与普通物理引擎不同,不接受普通物理引擎反应,不能跟普通的物理一视同仁。

好吧其实这个问题很水。

Solution:

使用OnControllerColliderHit来检测碰撞,不过这个函数不是碰撞的时候才调用一次,而是只要跟人物发生接触就会一直触发。


##

Problem:

5:Unity3D中相机清楚标志Clear Flags选择Depth Only或者Don’t Clear时Game View显示问题

具体原因未知,效果如图所示。

Unit3d图像缓存

Solution:

改成Solid Color或者Skybox就好,但是这样的话如果多重相机,该相机如果用来显示仪表盘,要是静态的图片还好,如果仪表盘需要更新估计会有问题。


##

Problem:

6:在使用Unity3D自带的NavMeshAgent的时候遇到的问题,人物无法在高度差的对象网格之中自动寻路。

Solution:

... Continue Reading →

关于最近

MyRainmeter

1:用GDI+重写了MyRainmeter的部分绘制代码。

why GDI+

怎么说呢,对于GDI的理解还只是在于表面,很多也仅仅限于会用(还是在查文档的前提下), 不过不管怎样,慢慢的积累就是一种进步。

GDI+在于图形绘制提供了很多GDI没有、或者说简化了GDI操作的函数封装。譬如对于32位位图PNG的绘制,透明图层在GDI里还得自己慢慢算,是一个很头疼的事。

how to use GDI+

为了使用GDI+,必须包含GDI+的头文件目录,以及调用GDI+lib库。

 // Using GDI+  #include <gdiplus.h>  #pragma comment(lib, "gdiplus.lib")  using namespace Gdiplus; 

然后的话是初始化和销毁环境,初始化和销毁工作应该在同一时段完成,以免因为后来忘了销毁,然后…… 在初始化之前先声明一个句柄,用于管理GDI+;

 protected: ULONG_PTR m_gdiplusToken; 

初始化

 // Startup GDI+  GdiplusStartupInput input; GdiplusStartup(&m;_gdiplusToken, &input;, NULL); 

销毁

 // Shutdown GDI+ ...               
                     
                Continue Reading →       
            

代码腐烂

唉,头疼。先码个头吧,改天得认真写一下。设计真是个头疼活,架构需要好好研究了。

Continue Reading →

eclipse中ssh搭建

惭愧,大学都快毕业了连个SSH框架都不会搭,于是又折腾了几天。

不求甚解不是好事,不善于总结也不是好事。

还是简单的说一下吧。

why

why eclipse.

1:我实在是不想为了一个网站就去用900多m的myeclipse。虽然myeclipse的确很方便的帮我们搭建好ssh环境。

2:myeclipse能够帮我们做很多事而不用管,但是如果不去了解其中的架构,不去了解struts如何拦截消息作出相应,不去了解spring如何管理struts和hibernate,不去了解hibernate持久化数据操作等消息,之后的编码也还是会一头雾水。

why ssh.

1:才疏学浅是个坎。 或者可以用ssi。到以后hibernate的轻量级和全自动化估计估计满足不了需求,但是短期内快速开发……

how

build a project

此过程的介绍纯属凑字数,不喜者请直接往下跳~~~~

打开eclipse以后新建一个dynamic web project就ok了。记得不要直接finish,在最后一步勾选Generate web.xml delopment descriptor.

eclipse_new_project

然后finish就ok了。然后可以新建一个页面来测试一下,记得部署好服务器。这里用的是tomcat 7.

how to use struts

要想使用struts,自然得有相关的包了。可以上apache.org上下载。http://struts.apache.org/   博主用的是struts2.

1:下载完解压以后,将struts的必要包放到WEB-INF/lib目录下。

一般的教程上说是6个必须包:

  • struts2-core-*.jar

  • xwork-core-*.jar

  • ognl-*.jar

  • freemarker-*.jar

  • commons-io-*.jar

  • commons-fileupload-*.jar

我这里运行的时候还需要以下两个包,不然会出错,不知道是不是tomcat的原因:

  • commons-lang*.jar

  • commons-logging-*.jar

2:添加完包以后,需要在web.xml中添加struts过滤器,这个一般的教程里都有,就不繁琐的介绍了。如下:

<!-- Struts Filter --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2Continue Reading →       
            

石墨建模综合实例-铅笔模型

折腾了3天铅笔的3d模型终于做好了, 有点水,但是结果还不错。

考虑要不要多买一支钢笔,这样子有一支躲起来的时候我还可以用另外一只来写日记。

[caption id=”attachment_494” align=”aligncenter” width=”640”]铅笔模型 铅笔模型[/caption]

用到的就是常见的多边形建模工具了;

还有就是切面工具

需要注意的:

插入面的时候需要注意的是距离太大的话,面会反过来,那样子挤出会有问题。

Continue Reading →

石墨建模-水龙头模型

这大概是世界上最丑的水龙头模型了。

过年前后几天什么都没做,建模、写代码都停了好一阵。

刚回到家的时候无从下手, 不知怎么的就忘光光了。

[caption id=”attachment_478” align=”aligncenter” width=”640”]水龙头模型 水龙头模型[/caption]

学习的事片刻不能放松, 自己的未来需要自己去掌控。

Continue Reading →

多边形建模加强实例-电视机

多边形建模的东西算是学的差不多了, 接下去要学习的是石墨建模, 做个综合实例来练练手吧。

[caption id=”attachment_459” align=”aligncenter” width=”640”]电视机 电视机[/caption]

好吧,这大概是史上最丑陋的电视机3d模型了。

做的很粗糙, 事实上做这个用基础模型建模会好很多,但是为了练习多边形建模常用的命令。

很多细节,比如边角的圆滑都没处理, 颜色也就这么地了。

哎, 头疼, 没有艺术细胞和艺术天分是硬伤,但是不能因为这个就放弃努力。

加油吧。

Continue Reading →

多边形建模综合练习-油壶

学了几天的多边形建模,今天(其实是昨天)进行了一个综合练习,做了个油壶,好吧,被某人嘲笑很丑了。

没有艺术的天分做这些的确是有些头疼的, 也没有经过系统的美感培训。

但是作为一项爱好和技能, 学习一些基础建模也是挺好的, 至少以后自己做游戏的时候可以建一些草模出来。

[caption id=”attachment_449” align=”aligncenter” width=”640”]油壶 油壶[/caption]

涉及到的工具:

1:多边形建模的点、边、多边形层级;

2:涡轮平滑(网格平滑);

其他一些笔记:

1:涡轮平滑和网格平滑的区别(算法不一样,前者省资源,后者可以进行更细节的修改);

2:点、线、面的控制,删除不必要的点线面以节省资源;

3:连接工具以增加分段数,循环和环形来选择,(相当于blender的环切ctrl+r);

4:针对1的一个特例,网格平滑的折痕;

Continue Reading →

多边形层级

仍然是比较基础和简单的多边形建模。

不过现在是多边形层级了,其实就是面层级吧,我理解是这样的。

上个画框的模型图。

[caption id=”attachment_432” align=”aligncenter” width=”640”]画框模型 画框的模型图[/caption]

用到的工具:

1:插入;

2:挤出;

3:轮廓;

4:分离;

多边形层级的其余工具:

1:挤出(多种挤出方式:组,局部法线,按多边形);

2:倒角;(倒角相当于挤出+轮廓);

3:桥;

4:从边旋转;

5:沿样条线挤出;

6:编辑三角剖分;

7:旋转;

8:其余一些貌似不常用的命令

Continue Reading →

边层级

中午不睡觉就是累。

困得要死,想在床上眯一会的,想了想还是爬起来把博客和日记写了吧。

今天的3D建模学的是多边形建模中的边层级。

[caption id=”attachment_421” align=”aligncenter” width=”640”]openbox 打开的箱子模型[/caption]

[caption id=”attachment_422” align=”aligncenter” width=”640”]魔方 魔方模型[/caption]

本模型涉及到的工具和命令:

1:可编辑多边形;

2:移除;

3:挤出;

4:切角;

5:修改器——壳

边层级其余的命令:

边层级的其余命令和点层级相似,如下:

1:移除;

2:分割;

3:挤出;

4:焊接;

5:切角;

6:桥:

7:连接;

Continue Reading →

ConfigParser类的设计

一天天的不知道折腾什么,MyRainmeter弄到现在连ConfigParser类都还没搞定。

还是节奏没控制好啊。

ConfigParser类主要是一些针对initialization file的读写操作,其实是没什么太大的难度的, 利用windows的api就可以完成。

上个草图吧, 真是草图, 可能是由于自己的设计理念还不是很清晰,所以总感觉漏了点什么或者欠缺考虑的。

以后再慢慢改了, 完整的做下来以后才知道哪些地方不足, 才能完整的理解一个软件的具体开发设计。(虽然还是挺水的。)

[swf:/assets/swfs/ConfigParser-class-design.swf 600 500]

其实这个图前几天就画完了,然后一直琢磨着把类实现以后写一篇完整的,现在看来还是有好多东西没弄好。

从封装来说应该做到高度封装降低与其他模块的耦合性,但是实现的时候总是会想到其他的怎么和这个契合, 虽然说低耦合但还是有耦合的。

接口设计没设计好,模块与模块之间的关系没搞清楚。 导致的后果可能是那边弄完了回过头来这边改改。

坤比说的对, 怎么样把活分好分下去给手下的人做好,才是一个领导者该关心的,领导者不应该过于关心某件小事的实现细节。就像昨天看《楚汉传奇》里韩信被拜大将时对其余将军说的话, 大将军是管普通将军的, 不是冲锋陷阵带兵的, 如何运筹帷幄调度兵马才是他应该关心的。

昨天微博上看到某大神写的关于求职面试之类的云云, 看完了诸多感想,但是总归到底只有一个,自己的实力还不够,书看的还不够多。

慢慢来了。慢慢积攒代码量,慢慢提高自身修为。

Continue Reading →

点层级2

今天学习了点层级,为可编辑多边形的一个小部分,没什么难度, 属于很基础性的内容了。

老样子,先上个图吧。

star

用到的命令:

1:可编辑多边形;

2:塌陷;

点层级的其他一些命令:

1:移除;

2:断开;

3:挤出;

4:连接;

5:目标焊接;

6:焊接;

7:移出孤立顶点等。

有一点貌似昨天忘了说的, 在max里按+/-可以缩放坐标轴。

Continue Reading →

点层级-床模型

最近的3Dmax学习进度有点水啊。

一个是现成的门模型、窗模型,都没有建出来,一个是由于不算太难, 另外一个是做着做着max就崩掉了……

好吧,简单的事都做不好不是一个好消息。

然后是动力学原理,2012的3dsmax居然调不出动力学工具栏……网上找了半天也没弄明白。 好吧……

然后是多边形建模篇了。

点层级的床模型。

先上图吧。

[caption id=”attachment_392” align=”aligncenter” width=”640”]床模型 床模型[/caption]

3dmax的多边形建模相对来说较blender简单一点(blender都没学太深没学明白,哎)。

本模型涉及到的工具和命令:

1:可编辑多边形;

2:网格平滑;

3:缩放(……);

貌似没了。

需要注意的:

1:分段数的合理设置;

2:网格平滑的迭代次数;

Continue Reading →

3Dmax欧式吊灯

花了两天终于用3dmax把欧式吊灯模型给建出来了。 好累。

欧式吊灯

马马虎虎也就将就着看了。

用到的建模方法或者技术等乱七八糟:

1:基础模型;

2:扩展模型;

3:可渲染样条线;

4:车削;

5:FFD修改器;

6:影响轴;

7:阵列(圆形);

8:组合;

Continue Reading →

MyRainmeter的第一记杂谈

前言:

MyRainmeter从开始计划要做到现在已经快一个月了。 最开始很单纯很简单的想把它给做好。 于是动手开始用c#写,到圣诞节的时候发布了两个版本。 然后就发现好多地方都考虑欠周全, 于是琢磨着重做, 用c++重新写。

最终选择了用mfc的多文档界面作为程序界面的一个雏形, 在其架构上开发。  不过对mfc是真心不熟悉, 在学校的时候只学会了用mfc制作基于对话框的程序, 学到的真是皮毛, 也没去深究过windows消息机制。

算是复习也算是重新学习了。 编程这个东西, 一段时间不用总会忘光光的。 有些人选择了钻研一门精到底, 有些人却选择了泛学。精者至高境界可以触类旁通知万物, 泛者可以看破浮尘返璞归真。 不能说谁好谁坏, 虽然现在的普世价值告诉我们术业有专攻所以前者看起来更加容易达到一定造诣。 毕竟要返璞归真是得经过好多年的修行才能得到的, 然后在外人眼里看来这不叫修行,这叫盲目的摸索没有目标。

我自己也一样, 大学泛泛而学学了好多, 最后精通的却没有, 所以屡屡碰壁。 到现在工作也没有找到。

但是回过头来想, 自己算不算抽象了好多技能定义了好多接口, 等到时候要用再细化, 演绎出想要的自己呢?

很多公司都说愿意找大学生, 因为大学生是一张白纸, 能够塑造成企业想要的形象。 但是现实往往告诉我们80%的企业没有精力和心情去培养你。 玉不琢不成器, 现在的企业需要的不是一块上好的玉石, 而是一块已经半成品的玉。 但是企业并不能完好的判断这块玉是不是自己想要的玉, 玉也不知道在这个企业能不能把自己雕琢成上等品。  大多数情况是彼此发现并不是所需要的, 于是又换一个企业, 这其中又有好多因为各种原因又继续换。 最终把自己的特色给雕琢成了粉末, 只剩下圆滑的鹅软石。

哎, 扯多了。 进入主题吧。

什么是MyRainmeter?

MyRainmeter是一款windows下的可执行程序, 研发的目的在于方便Rainmeter爱好者更方便的制作皮肤, 通过可视化操作,简化跟ini配置文件代码打交道的枯燥乏味。

初稿需求无非就是一句话:

支持可视化操作添加、修改和删除meter;

不过虽然只是这么小小的一句话,却包含了太多东西。

设计是个脑力活啊, 是个脑子的体力活。

哎, 今天忙活了一天光顾着折腾主题了, 早上去草草画了个草图。才发现逻辑还是没摸清, 软件工程貌似的确是个头疼的东西。 [swf:/assets/swfs/MyRainmeter-design.swf 600 500]

Continue Reading →

blender学习之路(一)

开始学习blender, 3D之路走起啊。

blender是一个开源的跨平台3D建模工具, 而且很小很轻巧, 支持python的api, 个人觉得很不错一下子就被吸引了, 不知道后续会怎么样,不过

对于一个新手来说, 已经足够强大了。

记录一下今天学习的心得吧, 虽然很少。

今天主要学习了快捷键的使用, 如下:

鼠标左键:默认是改变中心的位置, 点击的位置即为新的中心位置, 当选中物体进行变化的时候单击为将其定义到对应位置。

鼠标右键:选中物体

鼠标中键(滚轮): 缩放世界

鼠标中键(按住并移动鼠标): 旋转世界

Shift+鼠标中键(按住并移动鼠标): 平移世界

键盘A键:全选或者取消全选。

键盘S键:Scale, 缩放物体

键盘R键:Rotate, 旋转物体

键盘G键:Translate, 移动物体。 不明白为什么不是T

鼠标移到视图区右上角的三条斜杆处会变成十字形, 向左或者向下可以拖出另外一个一样的视图区, 这样我们一共可以拖出4个视图区。

对左上角的区域按数字键盘的7键和5键, 变成俯视图, 左下角的按1和5, 变成正视图, 右下角的按3和5, 变成侧视图。

界面是全英文的, 不过可以设置为中文开发环境, 单击“File”菜单下的“User Preferences”,找到“System”选项卡,勾选“International Fonts”筛选框,就会多出“Language”、“Translate”选项,“Language”选项用来选择语言种类(比如简体中文),“Translate”用来选择更改语言种类的地方(菜单和对话框)。然后就变成中文界面了, 无需重启。

今天学习的大概就这些了。嗯,上截图一张(其实今天啥也没干)。

blender工作界面截图

Continue Reading →

最大连续子向量的那点事

编程珠玑里第八章提到了最大连续子向量的几种解法, 代码就不上了, 书上就有, 网上也一大堆。 不过貌似有个问题, 如果全部都是负的数组,返回的应该是最大的负数。而按照书上的代码返回的是0, 或许是我太钻牛角尖了吧。

后面的习题里有问到如果是求最接近于0或者最接近于某个实数t的最大子向量,给的答案是用累加数组来辅助计算。 然后自己想了想, 最接近于某个实数, 也就是两个数之间距离最小, 那么就是取实数t和求出的向量和作差的绝对值最小,然后结合它给的算法, 就出来了。

话说这个算法真是高深的学问啊, 看到那个线性算法之后眼睛的确为之一亮。 想想自己在这方面的薄弱, 以及之前各种被完爆, 恨不得找地缝钻进去了。

每天努力一点, 离自己的梦想就更近一步。

Continue Reading →

设计模式学习之Abstract Factory模式

学习的进度最近又慢了, 各种各样的事, 然后总是容易把这个那个都弄不好。 实习还是没有着落, 实力还需加强, 努力吧, keep going.

抽象工厂模式。

工厂模式一共有5个:1.抽象工厂(Abstract Factory);2.工厂方法(Factory Method);3.建造模式(Builder);4.单例模式(Singleton);5.原型模式(Prototype)。

这5个都属于创建型模式, 而前面学习的Bridge模式、Adapter模式、Facade模式都属于结构型模式,Strategy模式则属于行为型模式。

先来看看抽象工厂的定义吧:为创建一组相关或相互依赖的对象提供一个接口, 而且无需指定它们的具体类。

面向对象的设计方法学最重要的一个概念之一就是封装变化, 将问题放到变化上来而不是放到具体的实现当中。 具体的实现是可变的, 但是这些变化是可封装的, 是共性的, 从概念视角和规约视角去分析问题。 我们要达到的目的是使各个类、或者说各个对象是高度内聚和低耦合的。

从定义分析, Client类和Product类是属于相关的,但是假如Product类有很多, 但是他们的功能大致类似,仅仅是实现方式或者实现表象不同, 如果client需要制定它们的具体类的话, client类和product类的耦合就会变大, 假如product类增加了一个新类, 就必须为client增加一个新的接口。

举个例子吧, 老样子。妹纸什么的最有爱了。 我约了MM一起去一个新开的餐厅吃饭, 听说气氛很不错, 和MM幽会吃饭肯定是必不可少的。 但是这个是新开的餐厅, 也不知道都有些什么菜。于是我把服务员叫来, 问他:冷菜有什么推荐菜么?小炒有什么推荐菜?汤类又有什么特色的呢? 服务员bulabula的说了一通,然后我和MM也是第一次来,就听服务员的推荐啦。 于是点菜功夫就完成了(ps:泡MM可别像我这么干, 你要知道,就算你不知道有什么菜, 你也得拿着菜单装模做样看一通,然后怎么点就你自己决定了, 比如什么名字听起来好听的 -。- 不然MM可能觉得你没主见神马的~然后说不定你就泪奔了)。当然,从生活的角度来说,这种纯粹由服务员推荐的例子不会太少,但是也不太多, 也有人认为服务员推荐的可能就是贵的, 味道不一定咋地, 很多人还是习惯自己看菜单点, 甚至有人都把菜单给背下来了。 生活么, 这样的做法太正常了, 但是从设计模式去分析的话,服务员提供的是一个接口, 使用接口的前提是你不关心他的内在实现, 并相信这个接口是工作正常、是可信任的。也就是说这些是有点理想化、可控制的, 而生活么, 很多事情是你无法掌控的, 比如地沟油神马的·~~

扯得有点远了,哈哈,跑题神马的。

上个图吧。

抽象工厂模式提供了一个新的分解方式——根据职责分解。 使用这种方法将问题分解为:

1:谁在使用特定对象(ApControl)(本例中的点菜的我);

2:谁来决定使用那些特定对象(AbstractFactory)(当然是推荐菜品的服务员啦);

当问题域中存在不同组的对象, 而且每组都用于不同情况时, 就应该使用AbstractFactory模式。可以根据各种理由定义对象的组。比如:

1:不同的操作系统(编写跨平台应用程序时);

2:不同的性能准则;

3:应用程序的不同版本;

4:应用程序的不同特点;

5:与地域有关的资源的不统计和(比如方言、日期格式);

本例子中不同的组就是凉菜、热菜甜品这些不同形式的菜啦~~~~

使用这种方式的优点就是, 我不用再去记那些菜名和菜的种类, 而且当店里有新的菜式出现时我也可以通过服务员知道。

Abstract Factory模式的关键特征:

意图:需要为特定的用户(或情况)提供对象组。

问题:需要实例化一组相关的对象。

解决方案:协调对象组的创建。提供一种方式, 将如何执行对象实例化的规则从使用这些对象的客户对象提取出来。

参与者与写作者:AbstractFactory为如何创建对象组的每个成员定义接口。一般每个组都有独立的ConcreteFactory进行创建。

效果:这个模式将“使用哪些对象”的规则与“如何使用这些对象”的逻辑分离开来。

实现:定义一个抽象类来指定创建哪些对象。 然后为每个组实现一个具体类。 可以用表或文件来完成同样的任务。

AbstractFactory模式的通用结构图:

[caption id=”attachment_574” align=”aligncenter” width=”596”]abstract-factory... Continue Reading →

设计模式学习之Bridge模式

情绪有点复杂啊, 真是不好。总是会因为各种各样的情绪影响着学习生活。

怎么说呢, 今天应该是开心的吧, 嗯,的确是的,幸福就在自己身边,是很美好的一件事。

好了,废话少说了, 很多事情都还没有结论,只能慢慢努力吧。只有自己实力强大了, 一切才有可能。

不怕寂寞, 不怕繁华。

Bridge、桥梁(桥接)模式。

——“将抽象与其实现解耦, 使他们都可以独立的变化。” 这个, 的确好抽象啊, 话说我也开不太懂这个概念, 抽象和实现解耦,独立变化是什么概念。

抽象是不同事物之间概念上的联系方式, 也就是说是共性部分, 而解耦是让各种事物互相独立地形式, 或者至少明确地声明之间的关系。

看了这个图以后貌似有了点新的理解,不过可能还是不得其门而入。

举个例子吧, 又带MM去“啃不起”吃汉堡,(-。-,真心啃不起啊, 而且个人也没觉得这里有多好吃的, 哈哈,不过幸好这不是真的,-。-, 那就意味着妹纸也没有哇), 然后我们假设这些汉堡都是要加番茄酱的, 他们有各种名字各种口味的汉堡, 然后番茄酱也有从酸到甜各个等级, 然后客户往往会要求加某个等级的番茄酱,但是每个客户都不一样,然后就会有很多配搭,那怎么样才能快速的分类呢? 如果每个汉堡都对应各个等级的番茄酱。 假如有3种口味的汉堡,3个等级的番茄酱, 那么就会出现如下的情况:

假设我又更多的汉堡和更多的番茄酱,那么这个阵容就很庞大了啊。

能够看得出来这种设计汉堡跟番茄酱的耦合性太高了。

怎么就觉得自己越讲越迷糊了, 看来还是例子举得不好啊。 哈哈

根据Bridge模式的定义和概念图,应该是如下所示的:

根据《设计模式解析》的例子, 它是形状和绘图两种对象,然后把绘图对联作为形状对象的一个包含对象, 用聚集来解决的这个问题。 把聚集关系作为桥梁吧,我是这么理解的。

我举得例子可能不太恰当, 貌似用抽象工厂模式也可以解决, 或许可能会更加合适。

ok,来看一看Bridge模式的关键特征:

意图:将一组实现与另一组使用它们的对象分离。 (看这个意思的话,两组之间是使用关系,跟抽象和实现两者的关系貌似不太符合)

问题:一个抽象类的派生类必须使用多个市县, 但不能出现类数量爆炸性增长。

解决方案:为所有实现定义一个接口,仅供抽象类的所有派生类使用。

参与者与协作者:抽象类为要实现的对象定义接口, 接口类为具体实现类定义接口, 抽象类的派生类使用接口类的派生类, 但不需要知道自己具体使用哪一个接口派生类。(跟抽象工厂方法类似)

效果:实现与使用实现的对象解耦, 提供了可扩展性(这点是的,抽象工厂的扩展性不如桥接模式好), 客户对象无需操心实现问题。

实现:1:将实现封装在一个抽象类中。2:在要实现的抽象的基类中包含一个实现的句柄。

注意:在java中可以在实现中用接口代替抽象类。

下面是《设计模式解析》中给出的Bridge模式的一般结构图:

最后说几个概念吧

1:“一条规则, 实现一次”;

2:“重构”;

3:“找到变化并封装之”;

4:“优先使用对象聚集而不是类继承”;

生活上的事还是不在这里说了。 还是等空了写一封放在阿狸童话里吧。

路漫漫, 加油。

Continue Reading →

设计模式学习之Strategy模式

这两天的学习进度很慢啊,心不静。

百度今天宣讲,6号笔试, 不知道自己能不能看完呢。 而且不是看完就完事,还要熟记于心,不然看了也是白看。

好了,废话少说吧,今天来看看Strategy模式。(我的学习过程是按《设计模式解析》一书来的,上面的模式进度是这样的。)

面向对象的三个基本特征:继承、封装和多态。 而设计模式看的最重要的就是这个封装的过程吧。

设计模式的三个要素:1:按接口编程;2:用聚合代替继承;3:超出变化并分装之。

按接口编程,而不要按实现编程,而是抽象出对象的本质,将对象之间的耦合性降低。 一个优秀的模式里面对象应该是高内聚、低耦合的。 也就是对象要对自己负责,而不过度依赖于其他对象。

我有一个泡MM的锦囊,里面有各种各样的泡妞绝招,百试不爽(做白日梦中,请勿打扰), 包括吃饭、唱歌、看电影等等。 我把它们都放在一起,到要用的时候找就行了。 但是久而久之, 就发现杂乱无章,而且有些MM已经一起吃过饭有自己的口味, 很难从其中找到对应的好策略。 万一比如你跟一个闽家的妹纸去吃四川火锅,把人家辣不高兴了, 然后你就哭吧。

于是我学聪明了, 我把每个MM的喜好都用一个小袋子装起来, 这样跟MM约会的时候,我就知道找到这个MM的袋子, 和MM共处一天的安排就有啦。(ps:貌似我举的这个例子不是很贴切哇, 这其中涉及到好多东西、或者用很多概念都能适配,而不一定就是我要讲的Strategy模式了-_-)

再来思考一下“优先使用对象聚集、对变化进行封装”着两个概念吧。

首先我们来看看泡MM的过程,似乎我们可以发现吃饭、唱歌、看电影这是和每个MM都应该要做的, 所以我把这些抽象成一个类,作为Strategy的基类。然后每个MM又有自己的喜好,比如吃饭口味不同、喜欢的电影的类型不同, 然后我就让每个MM去继承这个基类,实现之。这里可能会有人要说, 不是说尽量用聚集代替继承么? 你怎么还用继承? 好吧,笔者也是初学者,见谅见谅。 不过这里的继承是必须的, 不然怎么能把每个MM给特化呢? 那大家不都一样了吗? 然后我们再来看看什么地方要用聚集。 别忘了, 我们这可是一个泡MM的秘籍啊, 每个MM再不同, 我这辛苦了大半天弄得可是宝典啊, 所以嘛我把每个MM的特化锦囊聚集在一起, 就成为了一个“泡妞宝典”了, 然后我要用的时候我先找到这个“泡妞宝典”, 然后再找到对应的MM, 怎么样,这下不怕用错秘籍了吧? 果然是“宝典在手、MM我有”,哈哈哈哈。

ok扯淡扯了半天,回到正题吧。

so给出Strategy策略的定义:定义一系列的算法,将它们一个个封装起来, 并且使它们可以相互替换。Strategy模式使算法可以独立于使用它的客户而变化。(假设单位又来了一个新MM, 相处几天后新的MM锦囊一样收入宝典中,不影响我对其他MM的追求哦。 然后假设万一真不幸丢了一个MM的锦囊, 我也可以找个其他MM的来临时应付一下啦,当然是要接近的才合适)

Strategy模式的几条原则:

1:对象具有职责;(泡妞宝典的职责就是协助我泡MM啦)

2:这些职责不同的具体实现是通过多态的使用完成的。(每个MM都不一样,是因为每个MM都有独立的锦囊哦)

3:概念上相同的算法具有多个不同的实现, 需要进行管理。(不管理的话被偷了或者丢了咋办?你赔我么?)

上面的泡妞秘籍,是按每个MM不同来区分的,当然可能会有人问为什么不按吃饭、看电影等来区分呢? 首先对象要对自己负责, 你说是拿MM当对象还是拿吃饭当对象呢? 当然是MM啦, 而且拿吃饭当对象的话, MM与MM之间的耦合性就提高了, 而一个完整的MM的内聚性就变得很弱, 另外还有就是,假若多了一个活动、又多了一个MM,这个锦囊是不是就变得乱起来了呢?(参见《设计模式解析》里该章节的分支蔓延)

Strategy模式的关键特征:(《设计模式解析》)

意图:可以根据所处上下文,使用不同的业务规则或算法。

问题:对所需算法的选择取决于发出请求的客户或者要处理的数据。如果只有一些不会发生变化的算法,就不需要Strategy模式。

解决方案:将对算法的选择和算法的实现相分离。允许根据上下文进行选择。

参与者与协作者:Context、Strategy、ConcreteStrategy。(我、宝典、MM锦囊)

效果:1:定义了一系列的算法;2:减少分支switch和条件语句if的使用;3:必须要以相同的方式调用所有的算法(它们必须具有相同的接口)。各ConcreteStrategy与Context之间的相互作用可能需要在Context中加入获取状态的方法。

实现:让使用算法的类(Context)包含一个抽象类(Strategy)(我有一个宝典),该抽象类有一个抽象方法指定如何调用算法(宝典里有一个目录告诉我选择正确的MM锦囊)。每个派生类按需实现算法。(每个MM的锦囊都有自己的妙计)。

注意,在原型Strategy模式中, 选择所用具体实现的职责由Client对象承担, 并转给Strategy模式的Context对象。

路还很长, 我只能说。

不开心又能怎样。

Continue Reading →

设计模式学习之adapter模式

先来回顾一下facade模式的特点吧:对系统的一组接口用一个(或多个)更高层的接口封装,提供一个(或多个)统一接口来访问。

然后再来回顾一下设计模式的三个建议:1:按接口编程;2:尽量用聚合代替继承;3:找出变化并封装之;

Adapter模式的定义:将一个类的接口转换成客户希望的另一个接口。Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作。

举个例子吧,还是拿泡MM来说吧。我要追一个MM,这个MM很喜欢Apple公司的产品(真够有品位的- -),然后恰巧我有很多苹果的产品,比如iPod, iTouch, iPhone和iPad等(假设,绝对是假设),然后我邀MM到我家来玩这些东西必须先准备好啦,可是我突然发现我的“挨拍”被同事借走了然后一时还不回来, 咋办,眼看MM就要到了啊, 于是我打电话给另外一个哥们把他的山寨“挨拍”拿过来顶一阵了,然后为了不至于被MM发现,我把这个山寨”挨拍” 用我的正品”挨拍”的包装给包装起来,然后弄得像模像样的,看起来跟真的“挨拍”一样。(上帝保佑MM不会发现的)。

可能这个例子不够贴切,但是意思差不多是这个意思了,就是把跟指定接口不匹配的转换成指定接口,使他们能够一起工作(例子中的成为一套Apple系列产品来糊弄MM-_-)。哈哈,相信你能够找到更好的例子的。还有就是这个被转换的对象是要能够正常工作的,也就是对用户来说是一样的,看不出差别的。不然这个山寨挨拍估计就要拍到我脑袋上了,那就是我挨拍了。

ps:那些假冒伪劣产品的厂家很懂这个模式啊~~~~

为什么要使用Adapter模式?

1:希望使用指定的程序或方法,因为它要实现的功能是你需要的;

2:你无法将它直接加入你的程序中;因为它的接口或者调用方式与你原有程序的规范完全不同

(名称和参数列表不同、无法派生它)

所以你需要编写一个接口,通过适配使他们对于客户来说看起来是一样的。(例子中的“挨拍”包装过程才是真正的适配过程, 而不是拿山寨以假乱真)

Adapter模式的关键特征:(摘自《设计模式解析》)

意图:使控制范围之外的一个原有对象与某个接口匹配。

问题:系统的数据和行为都正确,但接口不符。通常用于必须从抽象类派生时。(例子中的山寨“挨拍”是可以用的,但是不是真的Apple产品)

解决方案:Adapter模式提供了具有所需接口的包装类。(将山寨“挨拍”用苹果的挨拍包装起来)

参与者与协作者:Adapter改变了Adaptee的接口,使Adaptee与Adapter的基类Target匹配。这样Client就可以使用Adaptee了,好像它是Target类型。(我改变了山寨“挨拍”的包装,使它跟Apple系列的产品配套,这样就可以拿来忽悠MM了,好像它就是真的挨拍一样)

效果:Adapter模式使原有对象能够适应新的类结构,不受其接口的限制。

实现:将原有类包含在另一个类中。让包含类与需要的接口匹配,调用被包容类的方法。

Adapter模式的两种类型:

1:对象Adapter模式。(依赖于一个对象(adapter)包含另一个对象(adaptee))

2:类Adapter模式。(通过多重继承实现)

类Adapter模式的工作原理是创建一个新类,该类同时从两个类继承:

1:从定义其接口的抽象类公开继承;

2:从访问其实现的原有类私有继承;

不过java是不支持多重继承的,所以实现起来的话应该用类聚集实现。这也是设计模式所强调的。不过这样的话就是对象Adapter模式了, 个人是这么理解的。

关于Facade模式和Adapter模式的区别的话,我想这个应该比较明显的吧,一个是是否需要多态、是否需要按指定接口设计, 以及是否需要更简单的接口。共同点的话是都存在既有接口。

大概就这么多了吧, 路漫漫其修远兮,加油~~~

Continue Reading →

设计模式学习之facade模式

原来还有设计模式这么一个东西, 接触面向对象语言有两年多了, 居然都不知道, 也难怪为什么自己面试会被各种拒绝了。这也跟自己学习的不求甚解有关系。怎么说呢, 就像那个学了一二三就说自己已经学会了知识一样,浅尝辄止。

好了,废话少说, 开始学习吧。

首先来复习一下什么是设计模式吧。有一个建筑设计师Alexander对模式的定义是“在某一背景下某个问题的一种解决方案”。

那么为什么要学习设计模式?1:复用解决方案;2:确立通用术语;3:易于修改和维护。

对于这点我深有体悟, 前几天去面试的时候被问到从观察者视角来阐述一个问题。然后我当时就被问倒了(请勿取笑)。然后还得麻烦面试官苦口婆心的跟我解释了半天。~~~好吧, 于是乎才了解了设计模式这个东西,然后才开始学习。

面向对象设计策略的三个建议:1:按接口编程;2:尽量用聚合替代继承;3:封装“变化”。(参考《设计模式》)。

关于其他的也不多说了,下面开始进入正题吧,Facade模式(门面模式)。

“为子系统中的一组接口提供一个统一接口。Facade模式定义了一个更高层的接口, 使子系统更加容易使用。”这是在《设计模式》一书中给出的Facade模式的定义。

话说没有接触设计模式的时候对概念这些看得都是一头雾水, 不知道是不是自己太笨了。哈哈,相信也有很多人跟我一样看不懂。

举个简单的例子吧。 我经常约MM一起去“啃不起”吃快餐(ps:一直在单身,请允许我幻想一下吧), 然后我们经常点的是薯条汉堡和可乐, 每次我们都要把三个都说一遍,很麻烦吧。 然后“啃不起”的Boss经过统计发现很多人都喜欢点这个“配搭”,于是他们推出了一个组合套餐, 包括了薯条汉堡和可乐,美其名曰“XX大套餐”。 于是我以后跟MM一起去就可以直接跟服务员说给我来一个“XX大套餐”, 怎么样?是不是方便多了呢?

上面的例子“XX大套餐”相当于一个新的接口,把“薯条”、“汉堡”、“可乐”三个接口封装成了一个接口,即相当于一个门面一样。

本来还想上张图的, 但是画图实在是画不好, visio和rational rose都画不太好,不过这个自己百度搜图搜一下会有很多,看一下也就明白了。

ps:上述例子中的服务员其实也就相当于了一个门面,不过考虑的角度不一样~~~

Facade模式关键特征:(摘自《设计模式解析》)

意图:希望简化原有系统的使用方式,需要定义自己的接口。

问题:只需要使用系统的子集、或者需要以一种特殊的方式与系统交互。

解决方案:Facade模式提供了一个新的接口。

参与者与协作者: 接口本身和各个子系统。

效果:简化了对所需子系统的访问过程。但是功能并不完整。

实现:定义一个(或多个)具备所需功能的新类。让新类使用原有的系统。

好吧,大概就这些了,Facade模式属于比较简单的模式,也比较好懂了,希望接下去的模式不会把自己难倒。

Continue Reading →