android设计模式:
概念:反复使用的代码的设计经验
单例模式:全局一个实例
建造者模式:让数据和表示分离并链式格式,比如Dialog
观察者模式:监听数据的变化
原型模式:复制新实例,而不影响原实例,也就是深浅拷贝
策略模式:为可能出现的行为添加拓展
工厂模式:提供一个接口,让子类决定实例谁
适配器模式:让不兼容的接口也可以工作
代理模式:提供代理以对其他对象间接的访问
迭代器模式:顺序访问某个对象内元素
备忘录模式:自动备忘对象的状态
命令模式:把请求封装为对象发送出去,比如handler,looper,message
责任链模式:链式传递
装饰者模式:
享元模式:从池中寻找,有就用,没有就创建
外观模式:类似游戏接口,只提供这个就行
桥接模式:将抽象与实现分离
状态模式:一个对象内状态的改变导致行为的改变
模板方法模式:让操作放在子类中实现
访问者模式:不改变原有,并添加新的操作
中介者模式:甲方-中介-乙方
解释器模式:需要解析器,比如AndroidManifest.xml就需要PackageParser
组合模式:个体和整体的关系
实例:
单例模式:提供全局一个实例
private static SingIn instance = null;
public static synchronized SingIn getInstance() {
if (instance == null)
instance = new SingIn();
return instance;
}
建造者模式(builder):让数据和表示分离并链式格式,比如Dialog
//自定义实例:
public class Person {
private String name;
private int age;
private Person(Builder builder) {
this.name=builder.name;
this.age=builder.age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
static class Builder{
private String name;
private int age;
public Builder name(String name){
this.name=name;
return this;
}
public Builder age(int age){
this.age=age;
return this;
}
public Person build(){
return new Person(this);
}
}
}
使用自定义实例:
Person.Builder builder=new Person.Builder();
Person person=builder
.name("什么")
.age(25)
.build();
观察者模式:当需要监听数据变化并变化后自动提醒
//收件人监听快递员信息,所以把收件人注册到快递员里 postman.add(boy1);
//抽象观察者
public interface Observer {
public void update(String message);//更新方法
}
//具体观察者
public class Boy implements Observer {
private String name;//名字
public Boy(String name) {
this.name = name;
}
@Override
public void update(String message) {//男孩的具体反应
System.out.println(name + ",收到了信息:" + message+"屁颠颠的去取快递.");
}
}
public class Girl implements Observer {
private String name;//名字
public Girl(String name) {
this.name = name;
}
@Override
public void update(String message) {//女孩的具体反应
System.out.println(name + ",收到了信息:" + message+"让男朋友去取快递~");
}
}
//抽象被观察者
public interface Observable {
void add(Observer observer);//添加观察者
void remove(Observer observer);//删除观察者
void notify(String message);//通知观察者
}
//具体被观察者-快递员
public class Postman implements Observable{
private List<Observer> personList = new ArrayList<Observer>();//保存收件人(观察者)的信息
@Override
public void add(Observer observer) {//添加收件人
personList.add(observer);
}
@Override
public void remove(Observer observer) {//移除收件人
personList.remove(observer);
}
@Override
public void notify(String message) {//逐一通知收件人(观察者)
for (Observer observer : personList) {
observer.update(message);
}
}
}
//测试
Observable postman=new Postman();
Observer boy1=new Boy("大国");
Observer boy2=new Boy("小明");
Observer girl1=new Girl("露露");
postman.add(boy1);
postman.add(boy2);
postman.add(girl1);
postman.notify("快递到了,请下楼领取.");
原型模式:复制新实例,而不影响原实例,对于基本数据类型使用浅拷贝,若有应用类型就再拷贝一次
//实例
public static class Card implements Cloneable {
private int num;
private Spec spec = new Spec();
public Card() {
}
public void setNum(int num) {
this.num = num;
}
public void setSpec(int length, int width) {
spec.setLength(length);
spec.setWidth(width);
}
@Override
public String toString() {
return "Card{" +
"num=" + num +
", spec=" + spec +
'}';
}
@Override
protected Card clone() throws CloneNotSupportedException {
Card card = (Card) super.clone();
card.spec = (Spec) spec.clone();//对spec对象也调用clone,实现深拷贝
return card;
}
}
public static class Spec implements Cloneable {//Spec也实现Cloneable接口
private int width;
private int length;
public void setLength(int length) {
this.length = length;
}
public void setWidth(int width) {
this.width = width;
}
@Override
public String toString() {
return "Spec{" +
"width=" + width +
", length=" + length +
'}';
}
@Override
protected Spec clone() throws CloneNotSupportedException {//重写Spec的clone方法
return (Spec) super.clone();
}
}
//运行
Card card1 = new Card();
card1.setNum(9527);
card1.setSpec(10, 20);
System.out.println(card1.toString());
System.out.println("----------------------");
Card card2 = card1.clone();
System.out.println(card2.toString());
System.out.println("----------------------");
card2.setNum(7259);
System.out.println(card1.toString());
System.out.println(card2.toString());
System.out.println("----------------------");
card2.setSpec(30, 40);
System.out.println(card1.toString());
System.out.println(card2.toString());
System.out.println("----------------------");
策略模式:当出现重复行为时,为了以后添加能有更好的扩展
//策略接口
public interface Strategy {
void travel();
}
//两个实现类
public class WalkStrategy implements Strategy{
@Override
public void travel() {
System.out.println("walk");
}
}
public class PlaneStrategy implements Strategy{
@Override
public void travel() {
System.out.println("plane");
}
}
//包装策略的类
public class TravelContext {
Strategy strategy;
public void TravelContext (Strategy strategy) {
this.strategy = strategy;
}
public void travel() {
if (strategy != null) {
strategy.travel();
}
}
}
//测试
TravelContext travelContext;
travelContext =new TravelContext (new WalkStrategy());
travelContext.travel();
travelContext =new TravelContext (new PlaneStrategy ());
travelContext.travel();
//若想加一种出行方式,可以这样
public class BikeStrategy implements Strategy{
@Override
public void travel() {
System.out.println("bike");
}
}
TravelContext travelContext =new TravelContext (new BikeStrategy ());
travelContext.travel();
工厂模式:提供一个接口,让子类决定实例谁,比如:bitmapfactory
1抽象产品类
public abstract class Product {
public abstract void show();
}
2
//具体产品类A
public class ProductA extends Product {
@Override
public void show() {
System.out.println("product A");
}
}
//具体产品类B
public class ProductB extends Product {
@Override
public void show() {
System.out.println("product B");
}
}
3抽象工厂类
public abstract class Factory {
public abstract Product create();
}
4
//具体工厂类A
public class FactoryA extends Factory {
@Override
public Product create() {
return new ProductA();//创建ProductA
}
}
//具体工厂类B
public class FactoryB extends Factory {
@Override
public Product create() {
return new ProductB();//创建ProductB
}
}
5 测试
//产品A
Factory factoryA = new FactoryA();
Product productA = factoryA.create();
productA.show();
//产品B
Factory factoryB = new FactoryB();
Product productB = factoryB.create();
productB.show();
适配器模式:让不兼容的接口也可以工作,比如各种adapter
1
interface Adapter {//适配器类
int convert_5v();//装换成5V
}
2
public class Electric {// 电源
public int output_220v() {//输出220V
return 220;
}
}
3
public class PhoneAdapter extends Electric implements Adapter {//通过继承源目标类的方式,不持有源目标对象
@Override
public int convert_5v() {
System.out.println("适配器开始工作:");
System.out.println("输入电压:" + output_220v());
System.out.println("输出电压:" + 5);
return 5;
}
}
4测试
Adapter phoneAdapter = new PhoneAdapter();
System.out.println("适配转换后的电压:" + phoneAdapter.convert_5v());
代理模式:当不能直接访问其他对象时,提供一个代理以对其他对象的访问,比如AIDL和service binder
静态代理:
1
public interface People {
void buy();//购买
}
2
public class Domestic implements People {
@Override
public void buy() {//具体实现
System.out.println("国内要买一个包");
}
}
3
public class Oversea implements People {
People mPeople;//持有People类的引用
public Oversea(People people) {
mPeople = people;
}
@Override
public void buy() {
System.out.println("我是海外代购:");
mPeople.buy();//调用了被代理者的buy()方法,
}
}
4测试
People domestic = new Domestic(); //创建国内购买人
People oversea = new Oversea(domestic); //创建海外代购类并将domestic作为构造函数传递
oversea.buy();
动态代理:Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法
1
public class DynamicProxy implements InvocationHandler {//实现InvocationHandler接口
private Object obj;//被代理的对象
public DynamicProxy(Object obj) {
this.obj = obj;
}
//重写invoke()方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("海外动态代理调用方法: "+method.getName());
Object result = method.invoke(obj, args);//调用被代理的对象的方法
return result;
}
}
2测试 通过反射代理
People domestic = new Domestic();
DynamicProxy proxy = new DynamicProxy(domestic);
ClassLoader classLoader = domestic.getClass().getClassLoader(); //获取ClassLoader
People oversea = (People) Proxy.newProxyInstance(classLoader, new Class[]{People.class}, proxy);
oversea.buy();//调用海外代购的buy()
迭代器模式:顺序访问某个对象内元素,而又不暴露该对象内部,比如数据库的cusor
1
public interface Iterator {
boolean hasNext(); //是否存在下一条记录
Object next(); //返回当前记录并移到下一条记录
}
2
//快递迭代类
public class DeliveryIterator implements Iterator {
private Aggregate aggregate;//容器对象
private int index;//当前索引
public DeliveryIterator(Aggregate aggregate) {
this.aggregate = aggregate;//初始化容器对象
}
@Override
public boolean hasNext() {//是否存在下一条记录
if (index < aggregate.size()) {
return true;
} else {
return false;
}
}
@Override
public Object next() {//返回当前记录并移到下一条记录
return aggregate.get(index++);
}
}
3
public interface Aggregate {
int size();//容器大小
String get(int location);//获取获取中指定位置的号码
void add(String tel);//添加号码到容器中
void remove(String tel);//从容器中移除号码
Iterator iterator();//返回容器的迭代器
}
4
//快递容器类
public class DeliveryAggregate implements Aggregate {
private List<String> list = new ArrayList<>();//内部使用list来存储数据
public int size() {//容器大小
return list.size();
}
public String get(int location) {
return list.get(location);
}
public void add(String tel) {
list.add(tel);
}
public void remove(String tel) {
list.remove(tel);
}
@Override
public Iterator iterator() {返回迭代器
return new DeliveryIterator(this);
}
}
5测试
Aggregate aggregate=new DeliveryAggregate();
aggregate.add("1111");
aggregate.add("2222");
aggregate.add("3333");
aggregate.add("9527");
Iterator iterator = aggregate.iterator();
while (iterator.hasNext()){
String tel = (String) iterator.next();
System.out.println("当前号码为:"+tel);
}
System.out.println("后面没有了");
备忘录模式:自动备忘对象的状态为日后使用,比如onSaveInstanceState和onRestoreInstanceState方法
1
public class Memento {//备忘录类
public int level;//等级
public int coin;//金币数量
public void setLevel(int level) {
this.level = level;
}
public void setCoin(int coin) {
this.coin = coin;
}
public int getLevel() {
return level;
}
public int getCoin() {
return coin;
}
}
2
public class Caretaker {//备忘录管理类
private Memento mMemento;
public void setMemento(Memento memento) {
mMemento = memento;
}
public Memento getMemento() {
return mMemento;
}
}
3
public class Game {//游戏类
private int mLevel = 1;//等级
private int mCoin = 0;//金币数量
@Override
public String toString() {
return "game{" +
"mLevel=" + mLevel +
", mCoin=" + mCoin +
'}';
}
public void play() {
System.out.println("升级了");
mLevel++;
System.out.println("当前等级为:" + mLevel);
System.out.println("获得金币:32");
mCoin += 32;
System.out.println("当前金币数量为:" + mCoin);
}
public void exit() {
System.out.println("退出游戏");
System.out.println("退出游戏时的属性 : " + toString());
}
public Memento createMemento() {//创建备忘录,即游戏存档
Memento memento = new Memento();
memento.setLevel(mLevel);
memento.setCoin(mCoin);
return memento;
}
public void setMemento(Memento memento) {
mLevel = memento.getLevel();
mCoin = memento.getCoin();
System.out.println("读取存档信息:" + toString());
}
}
4测试
System.out.println("首次进入游戏");
Game game = new Game();
game.play();//玩游戏
Memento memento = game.createMemento();//创建存档
Caretaker caretaker = new Caretaker();
caretaker.setMemento(memento);//保存存档
game.exit();//退出游戏
System.out.println("-------------");
System.out.println("二次进入游戏");
Game secondGame = new Game();
secondGame.setMemento(caretaker.getMemento());//读取存档
secondGame.play();//继续玩游戏
secondGame.exit();//不存档,嘿嘿嘿
命令模式:把请求封装为对象发送出去,比如handler,looper,message
1接收者角色
public class Receiver {
public void action() {//接收者执行具体的操作
System.out.println("接收者执行具体的操作");
System.out.println("开始执行关机操作:");
System.out.println("退出所有程序进程");
System.out.println("关机~");
}
}
2
//命令角色
public interface Command {
void execute();//执行命令
}
//具体命令角色
public class ShutdownCommand implements Command {//关机命令
private Receiver receiver;//接受者
public ShutdownCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
System.out.println("命令角色执行关机命令");
receiver.action();//调用接受者
}
}
3调用者角色
public class Invoker {//调用者
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
System.out.println("调用者执行命令");
command.execute();
}
}
4测试
Receiver receiver = new Receiver();//创建命令接收者
Command command = new ShutdownCommand(receiver);//创建一个命令的具体实现对象,并指定命令接收者
Invoker invoker = new Invoker(command);//创建一个命令调用者,并指定具体命令
invoker.action();//发起调用命令请求
责任链模式: 一个请求沿着一条“链”传递,直到该“链”上的某个处理者处理它为止。多个对象处理同一请求时,但是具体由哪个对象去处理需要运行时做判断
1
//抽象处理者类
public abstract class Postman {//快递员抽象类
protected Postman nextPostman;//下一个快递员
public abstract void handleCourier(String address);//派送快递
}
2
//具体处理者类
public class BeijingPostman extends Postman {//北京快递员
@Override
public void handleCourier(String address) {
if (address.equals("Beijing")) {//北京地区的则派送
System.out.println("派送到北京");
return;
} else {//否则交给下一个快递员去处理
nextPostman.handleCourier(address);
}
}
}
public class ShanghaiPostman extends Postman {//上海快递员
@Override
public void handleCourier(String address) {
if (address.equals("Shanghai")) {
System.out.println("派送到上海");
return;
} else {
nextPostman.handleCourier(address);
}
}
}
public class GuangzhouPostman extends Postman {//广州快递员
@Override
public void handleCourier(String address) {
if (address.equals("Guangzhou")) {
System.out.println("派送到广州");
return;
} else {
if (nextPostman != null)
nextPostman.handleCourier(address);
}
}
}
3
//创建不同的快递员对象
Postman beijingPostman = new BeijingPostman();
Postman shanghaiPostman = new ShanghaiPostman();
Postman guangzhouPostman = new GuangzhouPostman();
//创建下一个结点
beijingPostman.nextPostman=shanghaiPostman;
shanghaiPostman.nextPostman=guangzhouPostman;
//处理不同地区的快递,都是从首结点北京快递员开始
System.out.println("有一个上海快递需要派送:");
beijingPostman.handleCourier("Shanghai");
System.out.println("有一个广州快递需要派送:");
beijingPostman.handleCourier("Guangzhou");
System.out.println("有一个美国快递需要派送:");
beijingPostman.handleCourier("America");
装饰者模式: 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活
我们都知道Activity、Service、Application等都是一个Context
1
//抽象组件
public abstract class Room {
public abstract void fitment();//装修方法
}
2
//具体组件
public class NewRoom extends Room {//继承Room
@Override
public void fitment() {
System.out.println("这是一间新房:装上电");
}
}
3
//抽象装饰角色
public abstract class RoomDecorator extends Room {//继承Room,拥有父类相同的方法
private Room mRoom;//持有被装饰者的引用,这里是需要装修的房间
public RoomDecorator(Room room) {
this.mRoom = room;
}
@Override
public void fitment() {
mRoom.fitment();//调用被装饰者的方法
}
}
4
//具体装饰类
public class Bedroom extends RoomDecorator {//卧室类,继承自RoomDecorator
public Bedroom(Room room) {
super(room);
}
@Override
public void fitment() {
super.fitment();
addBedding();
}
private void addBedding() {
System.out.println("装修成卧室:添加卧具");
}
}
public class Kitchen extends RoomDecorator {//厨房类,继承自RoomDecorator
public Kitchen(Room room) {
super(room);
}
@Override
public void fitment() {
super.fitment();
addKitchenware();
}
private void addKitchenware() {
System.out.println("装修成厨房:添加厨具");
}
}
5测试
Room newRoom = new NewRoom();//有一间新房间
RoomDecorator bedroom = new Bedroom(newRoom);
bedroom.fitment();//装修成卧室
RoomDecorator kitchen = new Kitchen(newRoom);
kitchen.fitment();//装修成厨房
享元模式: 使用共享对象可有效地支持大量的细粒度的对象.大大减少了系统创建的对象,降低了程序内存的使用。我们接触到最多的还是Java中的String
1
//抽象享元角色
public interface IBike {
void billing(int time);
}
2
//具体享元角色
public class ShareBike implements IBike {//共享单车类
private int price = 1;//单价
private int total;//总价
@Override
public void billing(int time) {
total = price * time;
System.out.println("骑车花费了" + total + "元");
}
}
3
//享元工厂
public class BikeFactory {
private static Map<String, IBike> pool = new HashMap<>();//使用HashMap来保存IBike对象
public IBike getBike(String name) {
IBike bike = null;
if (pool.containsKey(name)) {//如果存在对象的话,直接使用
System.out.println("押金已交,直接用车:" + name);
bike = pool.get(name);
} else {//对象不存在的话,先创建对象
bike = new ShareBike();
pool.put(name, bike);
System.out.println(name + "交100押金,可以用车了。");
}
return bike;
}
}
4 测试
BikeFactory factory=new BikeFactory();
IBike ofo = factory.getBike("ofo");
ofo.billing(2);
IBike mobike = getBike("Mobike");
mobike.billing(1);
IBike ofo1 = getBike("ofo");
ofo1.billing(3);
外观模式: 要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行
1
//外观角色
public class GameSdk {
public void login() {//登录接口
//调用登录子系统的接口
LoginManager loginManager = new LoginManager();
loginManager.login();
}
public void pay(int momey) {//支付接口
//调用支付子系统的接口
PayManager payManager = new PayManager();
payManager.pay(momey);
}
}
2
//子系统
//登录系统
public class LoginManager {
public void login() {
System.out.println("打开登录界面");
System.out.println("进行登录操作");
System.out.println("登录成功");
}
}
//支付系统
public class PayManager {
public void pay(int momey) {
System.out.println("生成订单信息");
System.out.println("选择支付方式");
System.out.println("支付成功:" + momey + "元");
}
}
3测试
GameSdk gameSdk = new GameSdk();
gameSdk.login();
gameSdk.pay(6);
桥接模式: 将抽象部分与实现部分分离
1
//实现化角色
interface Clothes {
String getName();
}
2
//具体实现化角色
public class Uniform implements Clothes {
@Override
public String getName() {
return "校服";
}
}
public class Shirt implements Clothes {
@Override
public String getName() {
return "衬衫";
}
}
3
//抽象化角色
public abstract class Person {
Clothes mClothes;//持有衣服类的引用
public void setClothes(Clothes clothes) {
mClothes = clothes;
}
protected abstract void dress();//穿衣服
}
4
//具体抽象化角色
public class Student extends Person {
@Override
protected void dress() {
System.out.println("学生穿上" + mClothes.getName());
}
}
public class Coder extends Person {
@Override
protected void dress() {
System.out.println("程序员穿上" + mClothes.getName());
}
}
5测试
Clothes uniform = new Uniform();
Clothes shirt = new Shirt();
//不同职业的人穿衣服
Person coder = new Coder();
coder.setClothes(shirt);
coder.dress();
System.out.println("--------------------------------------");
Person student = new Student();
student.setClothes(uniform);
student.dress();
System.out.println("--------------------------------------");
student.setClothes(shirt);
student.dress();
状态模式 :一个对象内状态的改变导致行为的改变
模板方法模式:让操作延迟放在子类中实现
访问者模式:不改变原有,并添加新的操作
中介者模式:甲方-中介-乙方
解释器模式 :需要解析器,比如AndroidManifest.xml就需要PackageParser
组合模式:个体和整体的关系
这只是记录,方便查阅,但都是为了更好的使用,完毕