把毕业设计做完,论文也写好了,其他的事情也处理的差不多了,接下来再接着学习Android和Python的知识,今天先写一下关于几种模式的笔记
一、面向对象的六大原则
- 单一职责原则:Single Responsibility Principle,对一个类而言,其改变原因应该只有一个,这样有利于类的扩展
- 开闭原则:Open Close Principle,软件需要变化时尽量通过扩展的方式进行,而不是修改原来的类。需要重构代码,并不是简单的继承
- 里氏替换原则:Liskov Substitution Principle,引用基类的地方须透明使用其子类,核心思想是抽象,即方法由子类具体实现
- 依赖倒置原则:Dependence Inversion Principle,高层次模块不依赖于低层次模块的细节实现,通过接口或抽象实现。
http://blog.csdn.net/vebasan/article/details/8003118
- 接口隔离原则:Interface Segregation Principle,类之间的依赖关系应该建立在最小的接口上
- 迪米特原则:Law of Demeter,对象只了解其直接类
二、单例模式
单例模式的类只有一个实例存在,而且自行实例化并提供给整个系统。一般用于全局对象、资源消耗过多的对象,其关键特点为:
- 构造函数一般为Private,即构造函数私有化
- 以静态方法或枚举返回单例类对象
- 确保反序列化时不会重建对象
- public class Singleton{
- private static Singleton instance;
- private Singleton(){}
- public static synchronized Singleton getInstance(){
- if(instance == null){
- instance = new Singleton();
- }
- return instance;
- }
- }
优点:单例只在使用时才被实例化,一定程度上节约了资源
缺点:第一次加载时需及时实例化,反映稍慢,每次调用getInstance()都会同步,造成不必要的同步消耗,一般不建议使用懒汉模式
- public class Singleton{
- private volatile static Singleton instance = null;//volatile保证instance对象每次都从内存中读取
- private Singleton(){}
- public static Singleton getInstance(){
- if(instance == null){
- synchronized(Singleton.class){
- if(instance == null){
- instance = new Singleton();
- }
- }
- }
- return instance;
- }
- }
优点:资源利用率高,第一次执行getInstance()时单例对象才会被实例化,是使用最多的单例模式
缺点:第一次加载时需及时实例化,反映稍慢;由于Java内存模型(Java Memory Model,JMM)的原因偶尔失败;高并发下有小概率缺陷。这些缺点为DCL失效
- public class Singleton{
- private Singleton(){}
- public static Singleton getInstance(){
- return SingleHolder.instance;
- }
- //静态内部类
- private static class SingletonHolder{
- private static final Singleton instance = new Singleton();
- }
- }
第一次加载该类时并不初始化instance,在调用getInstance()时才初始化,此时JVM加载内部类SingletonHolder,这样不仅确保线程安全而且单例对象唯一,也延时了单例的实例化,弥补了DCL失效缺陷,是推荐使用的单例模式实现方法
- public enum Singleton{
- INSTANCE;
- private Singleton(){}
- }
不仅能避免多线程同步问题,而且还能
防止反序列化重新创建新的对
象。但是失去了类的一些特性,没有延迟加载,用的人也太少
如果上述例子中防止单例对象反序列化时重新生成对象,须加入以下方法
- private Object readResolve() throws ObjectStream Exception{
- return instance;
- }
在客户端,由于高并发情况较少,因此建议使用第2、3种单例模式。其优点如上所述,缺点最明显的一条是:若单例对象持有Context,易引发内存泄漏,此时最好为Application Context
三、Builder模式
将一个对象的构建和其表示分离,使得同样的构建过程可以创建不同的表示。其角色为:
- Product——产品抽象类
- Builder——抽象类,规范产品的组建,一般由子类实现具体的组件过程
- ConcreteBuilder——Builder具体类
- Director——统一组装过程
书中以Dialog为例,并讲解了WindowsManager,并没理解很深
四、原型模式
在此模型中需注意深浅拷贝问题,避免浅拷贝引起副本改变影响原始对象。
以PackageManagerService为例:PMS启动后1)扫描系统已安装的APK目录;2)解析APK目录下的AndroidManifest.xml文件;3)构件整个APK信息树。通过Intent跳转时,在ActivityInfo列表中查询,显示意图直接匹配,隐式意图有包名则匹配,无包名模糊匹配然后用户选择。
实例应用还是需要多练习!!!
五、工厂方法模式
定义一个用于创建对象的接口,让
子类
决定实例化哪个类,适用于复杂对象。重要的是抽象。其主要角色为:
- 抽象工厂:工厂方法模式的核心
- 具体工厂:实现了具体的业务逻辑
- 抽象产品:工厂方法模式创建的产品的基类
- 具体产品:实现抽象产品的某个具体产品对象
一个APP应用程序对应一个ActivityThread。Zygote孵化新的应用进程后,执行ActivityThread的main方法,在main中做一些处理,如准备Looper、消息队列,然后调用ActivityThread的attach方法将其绑定到ActivityManagerService中,接着读取Looper中的消息并分发。最终调用onCreate方法。
工厂方法模式有利于解耦,具体交由子类完成,有很好的可扩展性。但每次添加新产品时需编写新产品类,同时需引入抽象层,导致类结构复杂化。
五、抽象工厂模式
为创建一组相关或者相互依赖的对象提供一个接口,并不需要指定其具体类。一个对象族有相同的约束时可使用该模式。其主要角色为:
- AbstractFactory:抽象工厂,声明一组用于创建一种产品的方法,每个方法对应一种产品
- ConcreteFactory:具体工厂,实现了抽象工厂中的方法,生成一组具体的产品
- AbstractProduct:抽象产品,为每种产品声明接口
- ConcreteProduct:具体产品,定义具体产品对象,实现抽象产品接口中声明的业务方法
即具体工厂继承抽象工厂,并实现继承抽象产品的具体产品。
其缺点也是会导致工厂类过多。在Android中很少出现多个产品种类的情况,因此该模式的使用较少。
六、策略模式
定义一系列算法,并将每个算法封装,且使其可相互替换。将算法或策略抽象出来,提供一个统一的接口,不同算法或策略有不同实现类,客户端可以通过注入不同的实现对象来实现算法或策略的动态替换。
使用场景:1)针对同一类型问题的多种处理方式,仅是具体行为的差异;2)一个抽象类有多个子类,又需要if-else或switch-case来选择具体的子类。
角色介绍:
- Context:操作策略的上下文
- Stragety:策略的抽象
- ConcreteStragetyA、ConcreteStragetyB:具体策略实现
以时间插值器TimeInterpolator为例,讲述了不同插值器实现的策略。
属性动画:整体设计为Animator通过PropertyValuesHolder更新目标属性,若用户没设置目标属性的Property对象,以反射调用setter更新属性值;否则,通过Property的set设置属性值。属性值通过KeyFrameSet计算得到,然后又通过时间插值器根据时间流逝百分比计算属性值改变百分比,通过类型估值器计算改变后属性值,从而达到动画的效果。
十二、观察者模式
对象间是一种一对多的依赖关系,每当有对象状态改变时,则依赖于其的对象都会得到通知并被自动更新。适用于事件多级触发场景、跨系统的消息交换场景。角色介绍为:
- Subject:抽象主题,被观察者(Observable)
- ConcreteSubject:具体主题,观察者角色
- Observer
- ConcreteObserver
被观察者provider extends
Observable
变化后通知观察者me implements
Observer
。
在Android中,AdapterView中有一个内部类AdapterDataSetObserver,即观察者。在ListView中设置Adapter时会构建一个AdapterDataSetObserver,且注册到Adapter中。Adapter中还包含一个DataSetObservable,即被观察者,其发生变化后调用notifyDataSetChanged(实际是调用DataSetObservable的notifyChanged,遍历观察者的onChanged函数,获取数据集更新),再调用ListView的requestLayout重新布局,更新用户界面。
因为自己项目经验少,目前暂时写下理解的这几种,日后还会补充。