1.单例模式

1.1定义

确保某个类只有一个实例,而且自行实例化并向整个系统提供者个实例。

1.2单例的形式

饿汉模式:第一次就加载,用空间换时间。

public class SingleTon {

private static SingleTon instance = new SingleTon();

//构造函数不对外开放

private SingleTon() {

}

//通过静态方法或枚举进行调用

public static SingleTon getInstance() {

return instance;

}

}

懒汉模式:只有在调用的时候才进行加载,但是第一次比较慢,用时间换空间,效率不高,并且线程不安全。

public class SingleTonLH {

private static SingleTonLH instance;

//构造函数不对外开放

private SingleTonLH() {

}

//通过静态方法或枚举进行调用

public static synchronized SingleTonLH getInstance() {

if(instance == null){

instance = new SingleTonLH();

}

return instance;

}

}

双重加锁模式:使用volatile和synchronized进行修饰。

public class SingleTonDCL {

private static volatile SingleTonDCL instance;

//构造函数不对外开放

private SingleTonDCL() {

}

//通过静态方法或枚举进行调用

public static SingleTonDCL getInstance() {

if(instance == null){

synchronized (SingleTonDCL.class) {

if (instance == null){

instance = new SingleTonDCL();

}

}

}

return instance;

}

}

静态内部类:线程安全,并且什么时候使用什么时候调用。

public class SingleTonFinal {

// 构造函数不对外开放

private SingleTonFinal() {

}

// 通过静态方法或枚举进行调用

public static SingleTonFinal getInstance() {

return SingleTonHolder.sinstance;

}

//反序列化

private Object readResolve() throws ObjectStreamException {

return SingleTonHolder.sinstance;

}

/**

* 静态类部类

*/

private static class SingleTonHolder {

private static final SingleTonFinal sinstance = new SingleTonFinal();

}

}

枚举单例:

/**

* 枚举单例

*/

public enum SingleTonEnum {

INSTANCE;

public void dosamething(){

}

}

/**

* 调用方式

*/

class SingleTon {

private SingleTon(){

SingleTonEnum.INSTANCE.dosamething();

}

}

容器单例:

/**

* 容器实现单例模式

*/

public class SingleTonManger {

private static Map objMap = new HashMap();

// 构造函数不对外开放

private SingleTonManger() {

}

public static void registerService(String key, Object instance) {

if (!objMap.containsKey(key)) {

objMap.put(key, instance);

}

}

public static Object getService(String key) {

return objMap.get(key);

}

}

1.3优缺点

优点:全局一个,节约资源。在读文件方面,可以防止同时操作。

缺点:不易扩展,如果要扩展需要修改代码,违背了开闭原则。

1.4 Android源码对应模式

我们经常在Activity中通过getSystemService(String name)这个函数来获取系统服务,比如WMS,AMS,LayoutIlater等,这些服务都会在某一个时刻以容器单例的形式保存在应用中。在源码中我们知道各个服务都是保存在ContextImpl类中,在其中定义了一个SystemServiceRegistry类

final class SystemServiceRegistry {

// 存储所有系统服务的集合

private static final HashMap, String> SYSTEM_SERVICE_NAMES =new HashMap, String>();

private static final HashMap> SYSTEM_SERVICE_FETCHERS =

new HashMap>();

// 一个注册服务的并添加到结合的方法

private static void registerService(String serviceName, Class serviceClass,

ServiceFetcher serviceFetcher) {

SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);

SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);

}

// 静态语句块, 只在类第一次被加载的时候调用, 保证了服务只被添加一次.

static {

// 注册了LayoutInflate服务

registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,

new CachedServiceFetcher() {

@Override

public LayoutInflater createService(ContextImpl ctx) {

return new PhoneLayoutInflater(ctx.getOuterContext());

}});

registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,

new CachedServiceFetcher() {

@Override

public ActivityManager createService(ContextImpl ctx) {

return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());

}});

/**

* 后面省略一大坨的注册的服务代码

**/

}

//获得服务

public static Object getSystemService(ContextImpl ctx, String name) {

ServiceFetcher> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);

return fetcher != null ? fetcher.getService(ctx) : null;

}

}

2.Buider模式

2.1定义

把一个复杂的类的构建过程和它的表示进行分离

构建模式

2.2说明

Director:统一组装过程

Product:产品抽象类

builder:抽象的builder类,规范产品的组建

concreteBuilder:具体的builder类

一般实现

1,Product 建立抽象类

/**

* @describe 用户抽象类

*/

public abstract class Product {

protected String name;

protected String cardID;

protected int age;

protected String address;

//定义抽象方法

public abstract void setCardID();

public void setName(String name) {

this.name = name;

}

public void setAge(int age) {

this.age = age;

}

public void setAddress(String address) {

this.address = address;

}

//显示的内容让子类去实现

protected abstract String showProductInfo();

}

2.具体产品类

/**

* @describe product具体实现类

*/

public class SysProduct extends Product {

@Override

public void setCardID() {

//设置默认ID

cardID="10086";

}

@Override

protected String showProductInfo() {

return "User [name =" + name + ",cardID=" + cardID + ",age=" + age

+ "," + "address=" + address + "]";

}

}

3.定义抽象的buider类

/**

* @describe 抽象构造类

*/

abstract class Builder {

Product product;

public void buildName(String name) {

product.setName(name);

}

public void buildCardID() {

product.setCardID();

}

public void buildAge(int age) {

product.setAge(age);

}

public void buildAddress(String address) {

product.setAddress(address);

}

protected abstract void creat();

}

4.具体的buider实现类

/**

* @describe 具体的builder类

*/

public class AccountBuilder extends Builder {

SysProduct sysProduct;

@Override

protected void creat() {

sysProduct = new SysProduct();

sysProduct.setName("嘻嘻嘻");

sysProduct.setAge(20);

sysProduct.setCardID();

sysProduct.setAddress("中国");

System.out.println("Info : " + sysProduct.showProductInfo());

}

}

5.统一组装类director

/**

* @describe 统一组装类

*/

public class Director {

Builder mBuilder = null;

public Director(Builder builder) {

this.mBuilder = builder;

this.mBuilder.creat();

}

}

6.调用

/**

* @describe 测试类

*/

public class Test {

public static void main(String[] args) {

//统一组装

new Director(new AccountBuilder());

}

}

使用链式,简化Director

public class ChainProduct extends Product {

@Override

public void setCardID() {

// 设置默认ID

cardID = "10086";

}

@Override

protected String showProductInfo() {

return "Info : " + "User [name =" + name + ",cardID=" + cardID + ",age=" + age

+ "," + "address=" + address + "]";

}

public static class Builder {

ChainProduct product;

public Builder() {

product = new ChainProduct();

}

public Builder buildName(String name) {

product.setName(name);

return this;

}

public Builder buildAge(int age) {

product.setAge(age);

return this;

}

public Builder buildAddress(String address) {

product.setAddress(address);

return this;

}

public Builder buildCardID() {

product.setCardID();

return this;

}

public void creat() {

System.out.println(product.showProductInfo());

}

}

}

调用方式

new ChainProduct.Builder().buildAge(20).buildAddress("中国").creat();

2.3使用场景

相同的方法,不同的执行顺序,产生不同的事件结果

多个部件或者零件,都可以配装到一个对象,但是产生的运行结果不同

当初始化一个对象特别复杂,参数多,且很多参数默认的时候

2.4 优缺点

优点:封装性良好,使用可以使客户端不必知道产品内部组成细节。建造者独立易扩展。

缺点:会产生多余的builder对象和Director对象,消耗内存

2.5 android中使用

Director这个角色经常会被忽略. 而直接使用一个Builder来进行对象的封装, 并且这个Builder通常为链式调用, 它的每个setter方法都会返回this自身, 比如我们常用的AlertDialog。

// 一个粗略的创建dialog

// 创建构建者builder角色

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setIcon(android.R.drawable.sym_def_app_icon)

.setTitle("标题")

.setMessage("message")

// 设置点击等..

.setPositiveButton("确定", null);

// 构建

AlertDialog alertDialog = builder.create();

// 显示

alertDialog.show();

AlerDialog源代码:

public class AlertDialog extends Dialog implements DialogInterface {

// AlertController 这个对象会保存Builder对象中的各个参数

private AlertController mAlert;

// 实际上操作的是上面这个变量中的属性

@Override

public void setTitle(CharSequence title) {

super.setTitle(title);

mAlert.setTitle(title);

}

public void setMessage(CharSequence message) {

mAlert.setMessage(message);

}

// 省略一坨代码如各种setter等

// Builder以内部类的形式存在

public static class Builder {

// 1.存储AlertDialog的各个参数 如title,icon等

private final AlertController.AlertParams P;

// 构造函数

public Builder(Context context) {

this(context, resolveDialogTheme(context, 0));

}

// 2. 设置参数, 我们构建的Builder设置的参数就是这些方法

public Builder setTitle(int titleId) {

P.mTitle = P.mContext.getText(titleId);

return this;

}

public Builder setTitle(CharSequence title) {

P.mTitle = title;

return this;

}

// ....

// 3.构建AlertDialog, 传递参数

public AlertDialog create() {

// 4.因为已经通过builder设置了参数, 接下来就可以创建真正需要的AlertDialog对象

final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);

// 5.将Builder类中的成员变量P应用到AlertDialog类中

P.apply(dialog.mAlert);

dialog.setCancelable(P.mCancelable);

if (P.mCancelable) {

dialog.setCanceledOnTouchOutside(true);

}

dialog.setOnCancelListener(P.mOnCancelListener);

dialog.setOnDismissListener(P.mOnDismissListener);

if (P.mOnKeyListener != null) {

dialog.setOnKeyListener(P.mOnKeyListener);

}

return dialog;

}

}

}

可以看到Android源码中的AlertDialog并没有遵循GOF设计模式中经典的实现方式, 而是进行了变种, 但却使其使用更加的方便. 这里AlertDialog.Builder这个类同时扮演了范例中的builder,具体实现builder,Director的角色. 简化了Builder设计模式, 因为模块比较稳定不会存在变化, 根据具体场景简化模式, 正是体现了灵活运用设计模式的实例.

3.原型模式

3.1定义

用原型实例指定创建对象的种类,通过拷贝这个原型创建新的对象

原型模式

3.2说明

Client:客户端用户

Prototype:抽象类或者接口,声明具备clone能力。

concretePrototype:具体实现原型。

3.3使用场景

类的初始化需要消耗很多资源

通过new产生一个对象需要非常繁琐的数据准备或者访问权限

一个对象需要提供给其他对象访问,而且其他各个调用者都需要修改其值,可以通过原型拷贝多个对象提供给调用者调用。

3.4涉及到的知识点

赋值:对一个对象赋值一个对象,相当于两个对象对原来的对象都有控制权炒作一个另一个也有变化

//继承Cloneable类 相当于prototype接口。wordDocument相当于ConcreteProttype拥有赋值调用

public class WordDocument implements Cloneable {

// 文字

private String mText = "";

// 图片

private List mImages = new ArrayList();

public String getText() {

return mText;

}

public void setText(String mText) {

this.mText = mText;

}

public List getImages() {

return mImages;

}

public void setImages(List mImages) {

this.mImages = mImages;

}

public void addImage(String img) {

this.mImages.add(img);

}

/**

* 打印文档内容

*/

public void showDocument() {

System.out.println("----------- Word Content Start -----------");

System.out.println("Text : " + mText);

System.out.println("Images List: ");

for (String imgName : mImages) {

System.out.println("image name : " + imgName);

}

System.out.println("----------- Word Content End -----------");

}

}

赋值

浅拷贝:重写clone()方法,但是没有对引用类型进行拷贝,造成一个对象的引用类型发生变化另一个也会变化

//在类中添加clone 进行浅拷贝

@Override

protected WordDocument clone() {

try {

WordDocument doc = (WordDocument) super.clone();

doc.mText = this.mText;

doc.mImages = this.mImages;

return doc;

} catch (Exception e) {

}

return null;

}

浅拷贝

深拷贝:对引用类型再次进行clone()

//进行深度拷贝

ArrayList重写了clone的方法

@SuppressWarnings("unchecked")

@Override

protected WordDocument clone() {

try {

WordDocument doc = (WordDocument) super.clone();

doc.mText = this.mText;

//对mImages调用clone进行深度拷贝

doc.mImages = ((List) ((ArrayList) this.mImages).clone());

return doc;

} catch (Exception e) {

}

return null;

}

深拷贝

3.5 Android源码对应实现

ArrayList源码中的clone()

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable{

transient Object[] elementData;

private int size;

public Object clone() {

try {

ArrayList> v = (ArrayList>) super.clone();

v.elementData = Arrays.copyOf(elementData, size);

v.modCount = 0;

return v;

} catch (CloneNotSupportedException e) {

throw new InternalError(e);

}

}

Intent中实现

1.intent实现了Cloneable

public class Intent implements Parcelable, Cloneable {

}

2.对clone()重写

Intent

没有调用super.clone()使用了new Intent(this).当消耗不大的时候可以使用new

4.简单工厂模式

4.1定义

定义一个用于创建对象的接口,让子类决定实例化那个类

工厂方法模式

4.2使用场景

在任何需要创建复杂对象的地方,都可以使用工厂模式。但是能用new创建对象无需使用工厂方法模式。

4.3实现方式

一般实现流程

1.定义抽象产品类product

/**

* @describe 抽象产品类

*/

public abstract class Product {

/**

* 产品类的抽象方法,由具体的产品类去实现

*/

public abstract void method();

}

2、具体的产品实现类

/**

* @describe 具体实现类A

*/

public class ConcreteProductA extends Product {

@Override

public void method() {

System.out.println("我是具体的产品实现A");

}

}

/**

* @describe 具体实现类B

*/

public class ConcreteProductB extends Product {

@Override

public void method() {

System.out.println("我是具体的产品实现B");

}

}

3.抽象工厂类 factory

/**

* @describe 抽象工厂类

*/

public abstract class Factory {

/**

* 抽象工厂类方法

* @return

*/

public abstract Product CreateProuct();

}

4.具体实现工厂类

/**

* @describe 抽象工厂类的具体实现方法

*/

public class ConcreteFactory extends Factory {

@Override

public Product CreateProuct() {

return new ConcreteProductA();

}

}

5.客户端调用

/**

* @describe 调用类

*/

public class Client {

public static void main(String[] args) {

// 创建工厂

Factory factory = new ConcreteFactory();

// 创建产品

Product product = factory.CreateProuct();

// 调用产品的方法

product.method();

}

}

使用反射的方法进行工厂方法模式

1.创建反射工厂抽象类

/**

* @describe 使用反射的方便调用

*/

public abstract class Factory {

public abstract T createFactory(Class clz);

}

2.具体的实现工厂类

/**

* @describe 具体的实现工厂类

*/

public class ConCreateFactory extends Factory{

@SuppressWarnings("unchecked")

@Override

public T createFactory(Class clz) {

Product p = null;

try {

p = (Product) Class.forName(clz.getName()).newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

return (T) p;

}

3.调用方法

/**

* @describe 调用类

*/

public class Client {

public static void main(String[] args) {

// 创建工厂

Factory factory = new ConCreateFactory();

// 创建产品

Product product = factory.createFactory(ConcreteProductB.class);

// 调用产品的方法

product.method();

}

}

}

4.3 android中的简单工厂方法模式

onCreate是一个工厂方法

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(new FrameLayout(this));

}

}

通过onCrete这个方法,我们可以构建出任何样式的根布局。我们在不同的Activity#onCreate()方法将设置的布局通过setContentView()函数传递给frameworks并显示出来. 这不就是一个工厂模式的结构. 方法内部可以创建不同的对象, 产生不同的实例.

service中的onBind()也可以看成工厂方法模式

5.抽象工厂模式

5.1定义

为创建一组相关或者相互依赖的对象提供一个接口,而不需要指定它们的具体类

抽象工厂模式

5.2Android源码对应实现

抽象工厂在Android实现较少,基本上都可以用工厂方法模式解决。MediaPlayer底层使用的是抽象工厂模式

MediaPlayer

android源码使用方法,android源码中使用到的设计模式(创建型)相关推荐

  1. android颜色值的表示方法android:background=#FFFFFFFF的意思

    android颜色值的表示方法 android:background="#FFFFFFFF"的意思 Android中的颜色值是通过红(Red).绿(Green).蓝(Blue)三原 ...

  2. 2.5万字详解23种设计模式—创建型模式(简单工厂、工厂方法、抽象工厂、单例-多线程安全详解、建造者、原型)的详细解读、UML类图

    本文简述了各大设计模式,并通过UML和代码详细说明.本文大约共 2.5W 字,建议收藏.下方是本文的目录: 一.设计模式的认识 二.设计模式的分类 根据其目的 根据范围 三.设计模式的优点 四.设计模 ...

  3. 设计模式-创建型模式-工厂方法模式

    工程源码:c++设计模式-创建型模式-工厂方法模式https://download.csdn.net/download/qq_40788199/85541617 码云:https://gitee.co ...

  4. Android读取大文件方法,Android 读取大文件txt

    原文:http://zkl-1987.iteye.com/blog/1055394 由于现在TXT文本很多,特别是好多小说也是以这个文件格式出现,毕竟这个格式所占用不必要的空间比较小.像我这样的人就非 ...

  5. android的反调试方法,Android平台融合多特征的APP反调试方法与流程

    本发明涉及Android平台融合多特征的APP反调试方法,属于计算机与信息科学技术领域. 背景技术: 应用程序本身并不具备反调试的功能,但是动态调试是动态分析应用逻辑.动态脱壳等攻击方式所采取的必要手 ...

  6. android 开启子线程方法,android中开启子线程

    AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/ ...

  7. android 矢量图片使用方法,Android中的矢量图

    概述 VectorDrawable是通过XML文件中的一系列点,线和曲线及其相关颜色信息定义的. 使用VectorDrawable的主要优点是图像可扩展性. 它可以缩放而不损耗显示质量,这意味着相同的 ...

  8. android 设置全屏方法,Android中设置全屏的方法

    在开发中,我们经常需要把我们的应用设置为全屏,这里有两种方式: 一是在代码中设置; 二是在配置文件中设置 一. 在代码中设置 public class BaseActivity extends Act ...

  9. android toolbar的使用方法,Android中Toolbar的基本使用

    Android的标题栏是很重要的一个模块,App是否易用很大一部分要看标题栏.写这个博客的时候刚发现谷歌推出了一种新的标题栏实现方式. 它相对于以前的ActionBar来说,最大的变化是开发者可以在标 ...

最新文章

  1. java 怎么打印变量
  2. 对于当下国产CPU如火如荼有感
  3. 将redis当做使用LRU算法的缓存来使用
  4. react打包后图片丢失_如何快速构建React组件库
  5. Jquery操作复选框总结
  6. mysql innodb redolog_MySQL · 引擎特性 · InnoDB redo log漫游(转)
  7. 什么是kubernetes_Kubernetes为什么如此受欢迎?
  8. 【C++】 11_新型的类型转换
  9. PHP curl请求https
  10. android系统查看wifi密码,安卓手机如何查看WIFI密码
  11. 微信群接口(开发思路)
  12. 手机图片怎么转文本?
  13. Unity : Timeout while trying to pause the Unity Engine.应用闪退问题修复
  14. DDD,这东西到底是垃圾还是银弹?
  15. Nginx的 MIME TYPE问题导致的mjs文件加载出错的问题解决
  16. 查询活动开始时间和结束时间
  17. docker看这一篇就够了
  18. ffmpeg 连接抖音三个视频,做电脑桌面
  19. ThreeJs_投影
  20. 桂电的计算机专业研究生录取比例,桂电研究生就业待遇 桂林电子科技大学就业率...

热门文章

  1. CI/CD(持续集成构建/持续交付):如何测试/集成/交付项目代码?(Jenkins,TravisCI)
  2. Dell服务器与IntelX520万兆网卡兼容性问题解决过程
  3. 安卓日志点击无反应_长生之路游戏原型开发日志(三十七)
  4. 网络编程BaseIO介绍
  5. nohttp网络框架
  6. 学校计算机教室局域网的建立,校园局域网组建及配置.pdf
  7. 仿抖音视频自动播放html,vue 仿抖音视频播放切换
  8. linux 2种循环,只以换行符分割,不以空格分割。
  9. python具备的功能是_用了Python这么多年,揭秘Python不为人知的7大功能和特点!...
  10. 陕西机关事业单位工勤计算机考试成绩,2020年陕西省机关事业单位工人技术等级岗位考核公告发布 6月22日开始报名 9月中旬以后考核...