责任链模式:try-catch、有序广播、viewgroup事件传递
建造者模式:AlertDialog
装饰模式:Collections工具类、I/O、context
观察者模:android中的回调模式、listview的notifyDataChanged、rxjava
外观模式:context
模板方法模式:AsnycTask、Activity
策略:Volley
保证一个类在内存中的对象唯一性。
1,不允许其他程序用new创建该类对象。
2,在该类创建一个本类实例。
3,对外提供一个方法让其他程序可以获取该对象。
好处:
对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销
由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间
饿汉
public class HungurySingleton {
private static final HungurySingleton mHungurySingleton = new HungurySingleton();
private HungurySingleton(){
System.out.println("Singleton is create");
}
public static HungurySingleton getHungurySingleton() {
return mHungurySingleton;
}
public static void createString(){
System.out.println("createString in Singleton");
}
public static void main(String[] args){
HungurySingleton.createString();
}
}
懒汉
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static LazySingleton getInstance() {
// 第一次调用的时候会被初始化
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
public static void createString(){
System.out.println("create String");
}
public static void main(String[] args){
LazySingleton.createString();
}
}
懒汉安全
public class LazySafetySingleton {
private static LazySafetySingleton instance;
private LazySafetySingleton (){
}
public static void createString(){
System.out.println("create String");
}
public static void main(String[] args){
LazySingleton.createString();
}
//方法中声明synchronized关键字
public static synchronized LazySafetySingleton getInstance() {
if (instance == null) {
instance = new LazySafetySingleton();
}
return instance;
}
//同步代码块实现
public static LazySafetySingleton getInstance1() {
synchronized (LazySafetySingleton.class) {
if(instance == null){//懒汉式
instance = new LazySafetySingleton();
}
}
return instance;
}
}
DCL
假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance = new Instance(),该构造方法是一个非原子操作,编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只是在内存中开辟一片存储对象的区域后直接返回内存的引用,之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,所以需要加入volatile关键字,禁止指令重排序优化,从而安全的实现单例。
加入同步为了解决多线程安全问题。
加入双重判断是为了解决效率问题。
不写if语句的话,每次都会判断同步锁,这样写的话只在第一次判断并创建对象。以后在不会执行if里的代码了
public class DclSingleton {
private static volatile DclSingleton mInstance = null;
// private static DclSingleton mInstance = null;
private DclSingleton() {
}
public void doSomething() {
System.out.println("do sth.");
}
public static DclSingleton getInstance() {
// 避免不必要的同步
if (mInstance == null) {
// 同步
synchronized (DclSingleton.class) {
// 在第一次调用时初始化
if (mInstance == null) {
mInstance = new DclSingleton();
}
}
}
return mInstance;
}
}
静态内部类单例(推荐)
静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝,和单例的效果一样。
final表示变量只能一次赋值以后值不能被修改(常量),保证了安全性。
并且由于私有的属性,他人无法使用SingleHolder,不调用Singleton.getInstance()就不会创建实例。
public class StaticFactorySingleton {
//initailzed during class loading
private static final StaticFactorySingleton INSTANCE = new StaticFactorySingleton();
//to prevent creating another instance of Singleton
private StaticFactorySingleton(){}
public static StaticFactorySingleton getSingleton(){
return INSTANCE;
}
}
枚举单例(推荐)
public enum EnumSingleton {
//定义一个枚举的元素,它就是 Singleton 的一个实例
INSTANCE;
public void doSomeThing() {
// do something...
}
}
总结
饿汉:无法对instance实例进行延迟加载
懒汉:多线程并发情况下无法保证实例的唯一性
懒汉线程安全:使用synchronized导致性能缺陷
DCL:JVM即使编译器的指令重排序
静态内部类/枚举:延迟加载/线程安全/性能优势
外观模式的主要目的在于让外部减少与子系统内部多个模块的交互,从而让外部能够更简单得使用子系统。它负责把客户端的请求转发给子系统内部的各个模块进行处理。
使用场景
1)当你要为一个复杂子系统提供一个简单接口时。
2)客户程序与抽象类的实现部分之间存在着很大的依赖性
3)当你需要构建一个层次结构的子系统时
优点:
1)由于Facade类封装了各个模块交互的过程,如果今后内部模块调用关系发生了变化,只需要修改Facade实现就可以了。
2) Facade实现是可以被多个客户端调用的
public class ModuleA {
public void testFuncA() {
System.out.println("This is Function From 改变了");
}
}
public class ModuleB {
public void testFuncB() {
System.out.println("This is Function From ModuleB");
}
}
public class Facade {
private ModuleA moduleA = null;
private ModuleB moduleB = null;
private ModuleC moduleC = null;
private static Facade mFacade = null;
private Facade(){
moduleA = new ModuleA();
moduleB = new ModuleB();
moduleC = new ModuleC();
}
public static Facade getInstance() {
if(mFacade == null) {
mFacade = new Facade();
}
return mFacade;
}
public void testOperation() {
moduleA.testFuncA();
moduleB.testFuncB();
moduleC.testFuncC();
}
}
public class Client {
public static void main(String arg[]) {
Facade.getInstance().testOperation();
}
}
使用场景
(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2)当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式
ConcreteDecorator和Decorator都是继承component
public class DecoratorExample {
/**
* 抽象构件
*/
interface Component {
void operation();
}
/**
* 具体构件
*/
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("from ConcreteComponent");
}
}
/**
* 抽象装饰类
*/
class Decorator implements Component {
private Component component; //维持一个对抽象构件对象的引用
public Decorator(Component component) { //注入一个抽象构件类型的对象
this.component = component;
}
@Override
public void operation() {
component.operation(); //调用原有业务方法
}
}
/**
* 具体装饰类
*/
class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operation() {
//俩方法位置随便替换
super.operation(); //调用原有业务方法
addedBehavior(); //调用新增业务方法
}
//新增业务方法
public void addedBehavior() {
System.out.println("from ConcreteDecoratorA");
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
addedBehavior();
}
//新增业务方法
public void addedBehavior() {
System.out.println("from ConcreteDecoratorB");
}
}
public static void main(String[] args) {
//为了方便看就写到一个类里了,理解意思即可
// ConcreteComponent concreteComponent = new ConcreteComponent();
// Decorator decorator = new Decorator(concreteComponent);
// ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(decorator);
// ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(concreteDecoratorA);
// concreteDecoratorB.operation();
}
}
工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
工厂类可以根据条件生成不同的子类实例,并且这些对象需要具有共同的接口。
工厂方法模式(Factory Method)分为3种:
1、普通工厂模式
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图:
我们以一个例子来讲解:发送短信和发送邮件(具有共同的接口:发送)
public interface Sender {
/*
* 发送邮件或者短消息的共同接口
*/
public void sender();
}
/*
* 发送邮件的实现类
*/
public class MailSender implements Sender {
public void sender() {
// TODO Auto-generated method stub
System.out.println("this is mailsender!");
}
}
/*
* 发送短信的实现类
*/
public class SMSSender implements Sender {
public void sender() {
// TODO Auto-generated method stub
System.out.println("this is sms sender!");
}
}
public class SendFactory {
public Sender produce(String type){
if ("mial".equals(type)) {
//根据类型生产对象
return new MailSender();
}else if("sms".equals(type)) {
//根据类型生产对象
return new SMSSender();
}else {
System.out.println("类型输入错误");
return null;
}
}
}
工厂方法模式:这是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:
public class SendFactory {
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceMail();
sender.Send();
}
}
静态工厂模式:将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
工厂模式适用于:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。
这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!
public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
//工厂类
public class SendMailFactory implements Provider {
@Override
public Sender produce(){
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
public interface Provider {
public Sender produce();
}
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.Send();
}
}
相关源码:
https://github.com/peiniwan/DesignPattern.git