单例的概念
单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。
单例的好处
饿汉
code
public class HungrySingleton {
private static final HungrySingleton sHungrySingleton = new HungrySingleton();
public HungrySingleton() {
}
public static HungrySingleton getHungrySingleton() {
return sHungrySingleton;
}
}
不足之处
无法对instance实例做延时加载
public class LazySingleton {
private static LazySingleton instance;
public LazySingleton() {
}
public static LazySingleton getInstance(){
//第一次调用的时候会初始化
if (instance==null){
instance=new LazySingleton();
}
return instance;
}
}
懒汉线程安全
code
public class LazySafetySingleton {
private static LazySafetySingleton instance;
public LazySafetySingleton() {
}
//方法中声明synchronized关键字
public static synchronized LazySafetySingleton getInstance() {
if (instance == null) {
instance = new LazySafetySingleton();
}
return instance;
}
//同步代码块实现
public static LazySafetySingleton getInstance() {
synchronized (LazySafetySingleton.class) {
if (instance == null) {
instance = new LazySafetySingleton();
}
}
return instance;
}
}
不足之处 性能
DCL(双重检查锁机制)
code
public class DclSingleton {
private static volatile DclSingleton mInstance = null;
// private static DclSingleton mInstance = null;
private DclSingleton() {
}
public static DclSingleton getInstance() {
//避免不必要的同步
if (mInstance == null) {
//同步
synchronized (DclSingleton.class) {
if (mInstance == null) {
mInstance = new DclSingleton();
}
}
}
return mInstance;
}
}
不足之处
JVM的即时编译器中存在指令重排序的优化
静态内部类
code
public class StaticInnerSingleton {
private StaticInnerSingleton() {
}
public StaticInnerSingleton getInstance() {
return SingletonHolder.sInstance;
}
/**
* 类级的内部类,也就是静态类的成员式内部类,该内部类的实例与外部类的实例
* 没有绑定关系,而且只有被调用时才会装载,从而实现了延迟加载
*/
private static class SingletonHolder {
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static final StaticInnerSingleton sInstance = new StaticInnerSingleton();
}
}
优点 JVM本身机制保证了线程安全 没有性能缺陷
枚举
code
public enum EnumSingleton {
//定义一个枚举的元素,它就是Singleton的一个实例
INSTANCE;
}
优点 写法简单 线程安全
总结
1. Application
public class MyApplication extends Application {
public static MyApplication instance;
@Override
public void onCreate() {
super.onCreate();
//设置 Logger.init(TAG).logLevel(LogLevel.NONE) 可以设置为不打印日志
PosHelper.getPosApi().initSDK(this);
instance = this;
}
public static MyApplication getInstance() {
return instance;
}
}
2. 单例模式引起的内存泄露
3. EventBus的坑
概念
建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离
使用场景
Glide Okhttp
当构建一个对象需要很多参数的时候,并且参数的个数或者类型不固定的时候
实际代码分析
public class Product {
private String partA;//定义部件,部件可以是任意类型,包括值类型和引用类型
private String partB;
private String partC;
public String getPartA() {
return partA;
}
public void setPartA(String partA) {
this.partA = partA;
}
public String getPartB() {
return partB;
}
public void setPartB(String partB) {
this.partB = partB;
}
public String getPartC() {
return partC;
}
public void setPartC(String partC) {
this.partC = partC;
}
}
abstract class Builder {
//创建产品对象
protected Product mProduct = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
// 返回产品对象
public Product getResult() {
return mProduct;
}
}
public class ConcreteBuilder extends Builder {
@Override
public void buildPartA() {
}
@Override
public void buildPartB() {
}
@Override
public void buildPartC() {
}
}
public class Director {
private Builder mBuilder;
public Director(Builder builder) {
mBuilder = builder;
}
public void setBuilder(Builder builder) {
this.mBuilder = builder;
}
//产品构建与组装方法
public Product construct() {
mBuilder.buildPartA();
mBuilder.buildPartB();
mBuilder.buildPartC();
return mBuilder.getResult();
}
}
Builder模式的优点
Builder模式的缺点
总结
适配器模式定义
将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以在一起工作,其别名为包装器(Wrapper)
类适配器
类适配器定义
类的适配器模式把适配的类的API转换为目标类的API
UML结构图解释
code详解
public class Adaptee {
public void sampleOperation1() {
}
}
public interface Target {
void sampleOperation1();
void sampleOperation2();
}
public class Adapter extends Adaptee implements Target {
@Override
public void sampleOperation2() {
}
}
总结
对象适配器
对象适配器定义
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类
UML结构图解释
code详解
public class Adaptee {
public void sampleOperation1() {
}
}
public interface Target {
void sampleOperation1();
void sampleOperation2();
}
public class Adapter implements Target {
private Adaptee mAdaptee;
public Adapter(Adaptee adaptee) {
mAdaptee = adaptee;
}
@Override
public void sampleOperation1() {
mAdaptee.sampleOperation1();
}
@Override
public void sampleOperation2() {
}
}
总结
UI
Listview 的布局是由一条一条的 Item 组成的,这每一个 Item 又是一个 View。通过 Adapter 适配器这个桥梁将 View 添加到 ListView 中。
概念
装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。
使用场景
interface Component {
public void operation();
}
public class Decorator implements Component {
private Component mComponent;//维持一个对抽象构建对象的引用
public Decorator(Component component) {//注入一个抽象构建类型的对象
mComponent = component;
}
@Override
public void operation() {
mComponent.operation();//调用原有业务方法
}
}
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();//调用原有业务方法
addedBehavior();//调用新增业务方法
}
//新增业务方法
public void addedBehavior() {
}
}
5 . 装饰模式的优点
* 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。
* 可以通过一种动态的方式来扩展一个对象的功能。
* 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合。
概念
外观模式的主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单的使用子系统。它负责把客户端的请求转发给子系统内部的各个模块进行处理。
使用场景
public class ModuleA {
public void testFuncA() {
}
}
public class ModuleB {
public void testFuncB() {
}
}
public class ModuleC {
public void testFuncC() {
}
}
public class Facade {
private ModuleA mModuleA = null;
private ModuleB mModuleB = null;
private ModuleC mModuleC = null;
private static Facade sInstance = null;
private Facade() {
mModuleA = new ModuleA();
mModuleB = new ModuleB();
mModuleC = new ModuleC();
}
public static Facade getInstance() {
if (sInstance == null) {
sInstance = new Facade();
}
return sInstance;
}
public void testOperation() {
mModuleA.testFuncA();
mModuleB.testFuncB();
mModuleC.testFuncC();
}
}
public class Client {
public Client() {
Facade.getInstance().testOperation();
}
}
概念
将对象以树形结构组织起来,以达成“部分—整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
使用场景
实际代码分析
public abstract class File {
private String name;
public File(String name) {
this.name = name;
}
//操作方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract void watch();
//组合方法
public void add(File file) {
throw new UnsupportedOperationException();
}
public void remove(File file) {
throw new UnsupportedOperationException();
}
public void getChild(int position) {
throw new UnsupportedOperationException();
}
}
public class Folder extends File {
private List mFileList;
public Folder(String name) {
super(name);
mFileList = new ArrayList<>();
}
@Override
public void watch() {
StringBuffer fileName = new StringBuffer();
for (File file : mFileList) {
fileName.append(file.getName() + ":");
}
}
@Override
public void add(File file) {
mFileList.add(file);
}
@Override
public void remove(File file) {
mFileList.remove(file);
}
@Override
public void getChild(int position) {
mFileList.get(position);
}
}
public class TextFile extends File {
public TextFile(String name) {
super(name);
}
@Override
public void watch() {
}
}
public class testComposite {
public testComposite() {
TextFile textFileA=new TextFile("a.txt");
TextFile textFileB=new TextFile("b.txt");
TextFile textFileC=new TextFile("c.txt");
textFileA.watch();
Folder folder=new Folder("学习资料");
folder.add(textFileA);
folder.add(textFileB);
folder.add(textFileC);
folder.watch();
}
}
概念
定义一系列的算法,把他们一个个封装起来,并且使他们可互相替换。本模式使得算法可独立于使用它的客户而变化。
使用场景
实际代码分析
public class Context {
private AbstractStrategy mAbstractStrategy;
public void setAbstractStrategy(AbstractStrategy abstractStrategy) {
this.mAbstractStrategy = abstractStrategy;
}
public int calclatePrice(int km) {
return mAbstractStrategy.calculatePrice(km);
}
}
public interface AbstractStrategy {
//按距离来计算价格
int calculatePrice(int km);
}
概念
模板方法是通过定义一个算法架构,而将算法中的步骤延迟到子类,这样子类就可以复写这些步骤的实现来实现特定的算法。
使用场景
实际代码分析
public abstract class AbstractWork {
protected void getUp() {
}
protected abstract void gotoWork();
protected abstract void work();
protected abstract void goOffWork();
//TemplateMethod,大家都有共同的方法步骤
public final void newDay() {
getUp();
gotoWork();
work();
goOffWork();
}
}
public class BossWork extends AbstractWork {
@Override
protected void gotoWork() {
}
@Override
protected void work() {
}
@Override
protected void goOffWork() {
}
}
ublic class StaffWork extends AbstractWork {
@Override
protected void gotoWork() {
}
@Override
protected void work() {
}
@Override
protected void goOffWork() {
}
}