设计模式(十三)抽象工厂模式
本文首发于微信公众号「后厂技术官」
相关文章设计模式系列
前言此前讲解过简单工厂模式和工厂模式,这一篇我们来学习工厂系列的最后一个模式抽象工厂模式,建议在阅读此文前,请先阅读设计模式(四)简单工厂模式、设计模式(十)工厂方法模式这两篇文章。
1.抽象工厂模式定义抽象工厂模式可以说是是工厂方法模式的升级版,当需要创建的产品有多个产品线(产品族)时使用抽象工厂模式是比较好的选择。那什么是多个产品线呢?拿我们在设计模式(四)简单工厂模式、设计模式(十)工厂方法模式中学习的生产电脑的例子来举例,我们一直都是生产联想和惠普的电脑,但是电脑也有多个产品线:台式机、笔记本和平板等等,联想和惠普都在生产这些不同产品线上的电脑,使用工厂方法模式已经满足不了需求,这一篇文章我们就用抽象工厂模式来解决这一问题。
抽象工厂模式定义为创建一组相关或者相互依赖的对象提供一个接口,而无需指定它们的具体类。
抽象工厂模式UML图
在抽象工厂模式中有如下角色:
AbstractFactory:抽象工厂,它声明了用来创建不同产品的方法。
ConcreteFactory:具体工厂,实现抽象工厂中定义的创建产品的方法 ...
设计模式(十二)享元模式
本文首发于微信公众号「后厂技术官」
相关文章设计模式系列
享元模式定义享元模式是结构型设计模式的一种,是池技术的重要实现方式,它可以减少应用程序创建的对象,降低程序内存的占用,提高程序的性能。
定义:使用共享对象有效的支持大量细粒度的对象
要求细粒度对象,那么不可避免地使得对象数量多且性质相近,这些对象分为两个部分:内部状态和外部状态。内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境的改变而改变。而外部状态是对象依赖的一个标记是随环境改变而改变的并且不可共享的状态。享元模式结构图如下图所示。
在享元模式中有如下角色:
Flyweight:抽象享元角色,同时定义出对象的外部状态和内部状态的接口或者实现。
ConcreteFlyweight:具体享元角色,实现抽象享元角色定义的业务。
FlyweightFactory:享元工厂,负责管理对象池和创建享元对象。
享元模式简单实现某宝商城卖商品,如果每个用户下单都生成商品对象显然会耗费很多资源,如果赶上双11,那恐怖的订单量会生成很多商品对象,更何况商城卖的商品种类繁多,这样就极易会产生OOM。因此我们采用享元模式来对商 ...
Android系统架构与系统源码目录
前言技术博客终于可以恢复正常的更新速度了,原因是我编写的进阶书籍的初稿已经完成,窃以为它将会是Android应用书籍中最有深度的一本,可以说是《Android开发艺术探索》的姊妹篇。在这本书的最后一章我会分析Android底层源码,但是毕竟是一本Android应用开发的书,对于底层源码阅读也只能带大家入个门。因此,在博客中我会新开一个“系统源码解析”的系列,该系列的开篇就是本篇文章。
1.Android系统架构Android系统架构分为五层,从上到下依次是应用层、应用框架层、系统运行库层、硬件抽象层和Linux内核层。
应用层系统内置的应用程序以及非系统级的应用程序都是属于应用层。负责与用户进行直接交互,通常都是用Java进行开发的。
应用框架层(Java Framework)应用框架层为开发人员提供了可以开发应用程序所需要的API,我们平常开发应用程序都是调用的这一层所提供的API,当然也包括系统的应用。这一层的是由Java代码编写的,可以称为Java Framework。下面来看这一层所提供的主要的组件。
名称
功能描述
Activity Manager(活动管理器) ...
Android事件总线(四)源码解析otto
本文首发于微信公众号「后厂技术官」
前言上一篇文章中讲到了otto的用法,这一篇我们来讲一下otto的源码。可能有人觉得otto过时了,但是通过源码我们学习的是高手设计otto时的设计理念,这种设计理念是不过时的。
otto各个类的作用首先先来看一下otto的源码的各个类的作用,如下图所示。
如图所示,otto的源码并不多,主要的类的功能如下:
Produce、Subscribe:发布者和订阅者注解类。
Bus:事件总线类,用来注册和取消注册,维护发布-订阅模型,并处理事件调度分发。
HandlerFinder、AnnotatedHandlerFinder:用来查找发布者和订阅者。
EventProducer、EventHandler:分别封装发布者和订阅者的数据结构。
otto构造函数在使用otto时,首先要创建Bus类,Bus类的构造函数如下所示。
public Bus() { this(DEFAULT_IDENTIFIER); }
这个DEFAULT_IDENTIFIER是一个字符串”default”,this调用了Bus类的另一个构造函数: ...
Android事件总线(三)otto用法全解析
本文首发于微信公众号「后厂技术官」
前言otto 是 Square公司发布的一个发布-订阅模式框架,它基于Google Guava 项目中的event bus模块开发,针对Android平台做了优化和加强。虽然Square已经停止了对otto的更新并推荐使用RxJava和RxAndroid来替代它,但是otto的设计理念和源码仍旧值得学习,这一篇先来学习下otto的使用方法。
添加依赖库首先配置gradle,如下所示。
compile 'com.squareup:otto:1.3.8'
定义消息类与EventBus一样,我们接着定义消息类,它是一个bean文件,如下所示。
public class BusData { public String message; public BusData(String message){ this.message=message; } public String getMessage() { return message; ...
Android网络编程(十一)源码解析Retrofit
本文首发于微信公众号「后厂技术官」
相关文章Android网络编程系列
前言最近博客的产出确实很少,因为博主我正在写一本Android进阶书籍,两头很难兼顾,但是每个月也得至少发一篇博客。上一篇我们介绍了Retrofit的使用方法,这一篇我们照例来学习Retrofit的源码。
1.Retrofit的创建过程当我们使用Retrofit请求网络时,首先要写请求接口:
public interface IpService { @GET("getIpInfo.php?ip=59.108.54.37") Call<IpModel> getIpMsg();
接着我们通过调用如下代码来创建Retrofit:
Retrofit retrofit = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) .build();
Retrofit 是通 ...
这只是个开始,写在CSDN博客访问量破百万
对于很多技术博客大神,百万的访问量不值一提,但是对我来说,这是一个里程碑,也是一个新的开始,因此写此文来纪念下,希望几年后的我阅读此文仍旧能不忘此时的初心。
将写文和技术结合在一块很美妙笔者出生在教育家庭,父亲最早是个语文老师,笔者也在父亲的良好基因下,在学生时代语文成绩一直独领风骚,写的作文经常被当作范文在课堂上朗读。其实我语文从未努力过,很多同学认为是我父亲给我开小灶,其实他从未管过我的语文,所以,我只能认为我在语文上有些天赋吧。在高中文理分班时,我却意外选择了理科,因为当时学文的男生会被认为是智商有问题,所以从不服输的笔者开始学理,读完大学成了一个程序员。但是受到父亲的熏陶,我想成为个才子啊,连我的名字都是根据诗人戴望舒所取的,我不成为才子也对不起这个名字啊,哈哈。在成为程序员后,一位前辈说写博客对程序员有很大的好处,我便从最开始的转载别人的文章到自己写文章,这样既能写文又能提高技术,一举两得,岂不快哉。
中途懈怠,知耻而后勇在中途我降低了对自己的要求,文章也写的很少,在这个时段,Android在中国高速的发展开来,鸿洋、郭霖、任玉刚、徐宜生等优秀的博主相继出现,同时他们也获得 ...
Android网络编程(十)Retrofit2后篇[注解]
本文首发于微信公众号「后厂技术官」
相关文章Android网络编程系列
前言在上一篇Android网络编程(九)Retrofit2前篇[基本使用]中我们了解了Retrofit的最基本的GET方式访问网络的写法以及请求参数的简单介绍。这一篇我们来详细的了解Retrofit的注解。
1.GET请求访问网络动态配置URL地址:@PathRetrofit提供了很多的请求参数注解,使得请求网路时更加便捷。在这里我们仍旧访问淘宝ip库。其中,@Path用来动态的配置URL地址。请求网络接口代码如下所示。
public interface IpServiceForPath { @GET("{path}/getIpInfo.php?ip=59.108.54.37") Call<IpModel> getIpMsg(@Path("path") String path);}
在GET注解中包含了{path},它对应着@Path注解中的”path”,而用来替换{path}的正是需要传入的 “Strin ...
AsyncTask源码分析
本文首发于微信公众号「后厂技术官」
前言此前写过一篇AsyncTask源码分析的文章,但写的不是很好,最近看过了android7.0的AsyncTask源码,所以准备再写一篇。
1.Android 3.0版本之前的AsyncTask下面是Android 2.3.7版本的AsyncTask的部分源码。
public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; private static final BlockingQueue<Runnable> sWorkQueue = ...
设计模式(十一)策略模式
本文首发于微信公众号「后厂技术官」
相关文章设计模式系列
前言当我们写代码时总会遇到一种情况就是我们会有很多的选择,由此衍生出很多的if…else,或者case。如果每个条件语句中包含了一个简单的逻辑,那还比较容易处理,如果在一个条件语句中又包含了多个条件语句就会使得代码变得臃肿,维护的成本也会加大,这显然违背了开放封闭原则。这一讲我们就来讲策略模式,来看看它是怎么解决如上所说的问题的。
1.策略模式简介策略模式定义定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。策略模式模式使得算法可独立于使用它的客户而独立变化。
策略模式UML图
Context:用来操作策略的上下文环境。
Stragety:策略的抽象。
ConcreteStragetyA、ConcreteStragetyB:具体的策略实现。
2.策略模式简单实现这回我们还举武侠的例子,张无忌作为一个大侠会遇到很多的对手,如果每遇到一个对手都用自己最厉害的武功去应战这显然是不明智的,于是张无忌想出了三种应战的策略分别对付三个实力层次的对手。
定义策略接口策略接口有一个fighting的方法用于战斗:
pu ...
Android网络编程(九)Retrofit2前篇[基本使用]
本文首发于微信公众号「后厂技术官」
相关文章Android网络编程系列
前言Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,而OkHttp现在已经得到Google官方认可,不了解OKHttp的请查看本系列的前作。
1.使用前准备老生长谈,先配置build.gradle:
dependencies { ... compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.retrofit2:converter-scalars:2.1.0'//ConverterFactory的String依赖包}
当然别忘了在manifest加入访问网络的权限:
<uses-permission android:name="an ...
Android响应式编程(一)RxJava前篇[入门基础]
本文首发于微信公众号「后厂村码农」
1.RxJava概述ReactiveX与RxJava在讲到RxJava之前我们首先要了解什么是ReactiveX,因为RxJava是ReactiveX的一种java实现。ReactiveX是Reactive Extensions的缩写,一般简写为Rx,微软给的定义是,Rx是一个函数库,让开发者可以利用可观察序列和LINQ风格查询操作符来编写异步和基于事件的程序,开发者可以用Observables表示异步数据流,用LINQ操作符查询异步数据流, 用Schedulers参数化异步数据流的并发处理,Rx可以这样定义:Rx = Observables + LINQ + Schedulers。
为何要用RxJava想到异步的操作我们会想到android的AsyncTask 和Handler,但是随着请求的数量越来越多,代码逻辑将会变得越来越复杂而RxJava却仍旧能保持清晰的逻辑。RxJava的原理就是创建一个Observable对象来干活,然后使用各种操作符建立起来的链式操作,就如同流水线一样把你想要处理的数据一步一步地加工成你想要的成品然后发射给Sub ...
Android网络编程(八)源码解析OkHttp后篇[复用连接池]
本文首发于微信公众号「后厂技术官」
相关文章Android网络编程系列
1.引子在了解OkHttp的复用连接池之前,我们首先要了解几个概念。
TCP三次握手通常我们进行HTTP连接网络的时候我们会进行TCP的三次握手,然后传输数据,然后再释放连接。
TCP三次握手的过程为:
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服 ...
设计模式(十)工厂方法模式
本文首发于微信公众号「后厂技术官」
相关文章设计模式系列
前言在此前的设计模式(四)简单工厂模式中我们介绍了简单工厂模式,在这篇文章中我们来介绍下工厂方法模式,它同样是创建型设计模式,而且又有些类似,文章的末尾会介绍他们之间的不同。
1.工厂方法模式简介工厂方法模式定义定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式UML图找了下网上的UML图,都画的丑丑的,自己画吧,结果就出来这么一个更丑的UML图:
Product:抽象产品类。
ConcreteProduct:具体产品类,实现Product接口。
Factory:抽象工厂类,该方法返回一个Product类型的对象。
ConcreteFactory:具体工厂类,返回ConcreteProduct实例。
2.工厂方法模式简单实现参考设计模式(四)简单工厂模式这篇文章,我接着举电脑生产的例子。
创建抽象产品电脑产品类,它有一个start方法用于启动电脑:
public abstract class Computer{ public abstract vo ...
Android架构(一)MVP全解析
本文首发于微信公众号「后厂村码农」
前言关于架构的文章,博主很早就想写了,虽说最近比较流行MVVM,但是MVP以及MVC也没有过时之说,最主要还是要根据业务来选择合适的架构。当然现在写MVP的文章很多,也有很多好的文章,但是大多数看完后还是一头雾水,用最少的文字表述清楚是我一贯的风格(这里小小的装逼一下),所以还是自己总结比较靠谱。
1.回顾MVC讲到MVP前我们有必要回顾下MVC,MVC(Model-View-Controller,模型-视图-控制器)模式是80年代Smalltalk-80出现的一种软件设计模式,后来得到了广泛的应用,用一种业务逻辑、数据、界面显示分离的方法组织代码,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
android的MVCAndroid中界面部分也可以采用了MVC框架,MVC的角色定义分别为:
模型层(Model)我们针对业务模型,建立的数据结构和相关的类,就可以理解为Model,Model是与View无关,而与业务相关的。
视图层(View)一般采用xml文件或者java代码进行界面的描述,也可以使用javascript+ ...
Android事件总线(二)EventBus3.0源码解析
本文首发于微信公众号「后厂技术官」
前言上一篇我们讲到了EventBus3.0的用法,这一篇我们来讲一下EventBus3.0的源码以及它的利与弊。
1.构造函数当我们要调用EventBus的功能时,比如注册或者发送事件,总会调用EventBus.getDefault()来获取EventBus实例:
public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); } } } return defaultInstance;}
很明显这是一个单例模式,采用了双重检查模式 (DCL),不了解的同学可以查看设计模式(二)单例模式 ...