从android中学习23种设计模式,透彻解析

@Override

public void select() {

realImage.select();

}

}

//使用

DataBase proxyDb = new ProxyDB();

proxyDb.select();

这里用了ProxyDB 这个代理类,去访问数据,并没有直接去访问数据库。在android中,当我们编写好AIDL文件后,编译器会自动给我们增加一些代码

public interface IRemoteService extends android.os.IInterface{

public static abstract class Stub extends android.os.Binder implements …{

public static com.learnaidl.IRemoteService asInterface(…) {

return new …Proxy(obj);

}

private static class Proxy implements com.learnaidl.IRemoteService{

}

}

}

//使用

IRemoteService.Stub()

通过IRemoteService的Stub类拿对象,这个对象是通过一个代理类创建出来的。

换个角度看,代理模式也就是 实现了一个接口,并完成了一个方法,这个方法可以去做任何事情。

7、外观模式(Facade Pattern)

目的:降低系统复杂度

优点:提高灵活性,安全性

缺点:违反了开闭原则、迪米特原则,改东西相对麻烦

实现:

//接口 有个打开的动作

public interface Action {

void open();

}

//灯 实现了 开灯

public class Lamp implements Action {

@Override

public void open() {

System.out.println(“开灯”);

}

}

//电视 实现了 打开电视

public class TV implements Action {

@Override

public void open() {

System.out.println(“开电视”);

}

}

//遥控器 可以控制灯 和电视

public class RemoteControl {

Action lamp;

Action tv;

public RemoteControl(){

lamp = new Lamp();

tv = new TV();

}

public void openLamp(){

lamp.open();

}

public void openTv(){

tv.open();

}

}

遥控器既可以开灯,又可以开电视。可见这个“遥控器”职责并不单一。也不用局限于接口,如果是功能聚合到一个类中,依然可以叫外观模式。想象成 前台、接待员

在android中,Context就用了外观模式,Context可以打开Activity,可打开Service,广播等等。

8、装饰器模式(Decorator Pattern)

目的:解决扩展子类膨胀的问题,比如摊煎饼,可以摊煎饼前,煎个鸡蛋,摊煎饼后,撒点酱

优点:灵活扩展

缺点:过多的装饰,会很复杂

实现

//一个煎饼接口

public interface Pancake {

void pancake();

}

//牛肉煎饼

public class BeefPancake implements Pancake{

@Override

public void pancake() {

System.out.println(“牛肉煎饼”);

}

}

//工作人员

public class Worker {

Pancake pancake;

public Worker(){

pancake = new BeefPancake();

}

public void makePancake(){

System.out.println(“煎鸡蛋”);

pancake.pancake();

System.out.println(“撒酱”);

}

}

//使用

Worker worker = new Worker();

worker.makePancake();

说白了,装饰模式,装饰东西,实际作用的前后装饰一些其他内容。在android中,Context,ContextImpl也就是个装饰模式,我们肯定会在startActivity()前后做点业务操作。

9、享元模式(Flyweight Pattern)

目的:为了解决大量创建相同对象,可能造成OOM

优点:减少重复创建对象,降低内存

缺点:提高了系统的复杂度,如果固定了一些对象,当被改变时候,会造成混乱

实现:

//假设有个请求的类

public class Request {

}

//通过一个地方 去拿请求

public class HttpFactory {

public static final HashMap<String,Request> requestMap = new HashMap<>();

public Request getRequestList(String name) {

Request request = (Request) requestMap.get(name);

if(request==null){

request = new Request();

requestMap.put(name,request);

}

return request;

}

}

//使用

HttpFactory factory = new HttpFactory();

Request request1 = factory.getRequestList(“baidu”);

//假设过了一会

Request request2 = factory.getRequestList(“baidu”);

相当于是缓存了一块地方,把对象放进去,需要对象的时候就从这里面取,如果相同需求,则会返回已有的对象。

在android中,获取Message,可以通过Message.obtain()去获取Message。在JVM中缓存了很多字符串。 可以说我们任何时候都在使用享元模式。

10、组合模式(Composite Pattern)

目的:用来描述整体和部分的关系,比如在树中,一个结点可以是根节点,也可以是叶子节点

优点:调用简单,结点可以自由增加

缺点:在组合模式中,依赖的都是实现类,而不是接口,违反了依赖倒置原则

实现:

//二叉树

public class ListNode {

int data;

ListNode left;

ListNode right;

}

二叉树的结点,既可以是根节点,又可以是叶子节点。

在android中,View和ViewGroup的关系,ViewGroup既可以是一个View,又可以包含View。

11、适配器模式(Adapter Pattern)

目的:解决两个不兼容接口的桥梁,兼容转换

优点:让两个没有关联的类一起运行,提高复用

缺点:使用过多,会让系统变的凌乱

实现:

//定义适配器类

public class Adapter {

public void getView(int i){

System.out.println(“给出View”+i);

}

}

//ListView 继承了Adapter

public class ListView extends Adapter{

public void show(){

System.out.print(“循环显示View”);

for(int i=0;i<3;i++){

getView(i);

}

}

}

//GridView继承了Adapter

public class GridView extends Adapter{

public void show(){

getView(i);

}

}

适配器模式可以用继承实现,这里没有更高的抽象,当然也可以把Adapter的内容抽象出去,仅仅演示,ListView、GridView适配了Adapter类。

在android中,ListView、RecyclerView都是用了适配器模式,ListView适配了Adapter,ListView只管ItemView,不管具体怎么展示,Adapter只管展示。就像读卡器,读卡器作为 内存和电脑 之间的 适配器。

12、桥接模式(Bridge Pattern)

目的:将两个能够独立变化的类分开,不用继承,继承会造成类的爆炸增长

优点:抽象分离,易扩展,细节透明

缺点:会增加系统的设计难度

实现:

//颜色接口

public interface Color {

void draw(String box);

}

//红色 完成方法 红色的something

public class RedColor implements Color{

@Override

public void draw(String sth) {

System.out.println("red "+ sth);

}

}

//抽象类 盒子

public abstract class Box {

Color color;

public Box(Color color){

this.color = color;

}

abstract void getBox();

}

//实现类 红色盒子

public class RedBox extends Box {

public RedBox(Color color) {

super(color);

}

@Override

void getBox() {

this.color.draw(“box”);

}

}

//使用

RedColor redColor = new RedColor();

Box box = new RedBox(redColor);

box.getBox();

如果类存在两个维度的变化,比如颜色可能有红色、绿色,包可能有手提包,钱包。对于这两个维度的变化,适合用桥接。更直观的说,比如一个USB线左边可以插不同的手机,右边可以插不同的电源。

在android中,整个View的视图,View、Button、ViewGroup等等都是在View这个维度上的变化,都有onDraw()方法来实现不同的视图。另一个维度就是把View绘制到屏幕上。私以为,这RexBox相当于一个View,RedColor相当于绘制到屏幕上。

行为型
13、模板模式(Template Pattern)

目的:固定了一些方法,只要照着做就行,比如把大象放进冰箱,打开冰箱,放进冰箱,关闭冰箱

优点:行为由父类控制,便于维护

缺点:导致类增多,系统变大

实现:

public abstract class BaseActivity {

abstract void onCreate();

abstract void onDestory();

}

public class HomeActivity extends BaseActivity {

@Override

void onCreate() {

}

@Override

void onDestory() {

}

}

它的主旨就是抽象出公共的方法,子类照着重写就行,行为由父类控制这个。。。作为android开发者天天都在用。。。

14、策略模式(Strategy Pattern)

目的:解决很多if else的情况

优点:可以避免多重判断条件,扩展性好

缺点:类会增多

实现:

//假如RecyclerView 这样写

public class RecyclerView {

private Layout layout;

public void setLayout(Layout layout) {

this.layout = layout;

if(layout == “横着”){

}else if(layout == “竖着”){

}else if(layout==“格子”){

}else{

}

this.layout.doLayout();

}

}

//这样写if就很多了

//排列的方式

public interface Layout {

void doLayout();

}

//竖着排列

public class LinearLayout implements Layout{

@Override

public void doLayout() {

System.out.println(“LinearLayout”);

}

}

//网格排列

public class GridLayout implements Layout{

@Override

public void doLayout() {

System.out.println(“GridLayout”);

}

}

public class RecyclerView {

private Layout layout;

public void setLayout(Layout layout) {

this.layout = layout;

this.layout.doLayout();

}

}

这里直接举了android中RecyclerView的例子,我们给RecyclerView选择布局方式的时候,就是选择一个策略。

15、中介者模式(Mediator Pattern)

目的:解决对象与对象之间的耦合关系

优点:降低复杂度,各个类之间解耦

缺点:中介者会过于庞大不好维护

实现:

//聊天室

public class ChatRoom {

public static void showMessage(User user,String msg){

System.out.println(user.name+“:”+msg);

}

}

//用户

public class User {

String name;

public User(String name){

this.name = name;

}

public void sendMessage(String msg){

ChatRoom.showMessage(this,msg);

}

}

//使用

User h1 = new User(“h1”);

User h2 = new User(“h2”);

h1.sendMessage(“hello”);

h2.sendMessage(“you too~”);

这个聊天室就相当于个中介者,给两个人传递消息。如果聊天室新增功能,会导致聊天室的代码越来越多,不好维护。

在android中,无时无刻都在使用中介者,MVP 的 P ,MVC的 C ,MVVM 的 VM,你和我。???

16、观察者模式(Observer Pattern)

目的:一个对象改变通知其他对象,保证协作

优点:观察者和被观察者是抽象耦合的,也就是说通过抽象方法,给具体的类通知

缺点:如果观察者有很多,被观察者发消息,会慢,如果不小心观察者和被观察者有依赖,会循环引用

实现:

//抽象类 做作业

public abstract class DoWork {

protected Teacher teacher;

abstract void doHomeWork(int i);

}

//老师

public class Teacher {

private List students = new ArrayList<>();

private int index;

public void attach(Student student){

this.students.add(student);

}

public void dispatchHomeWork(int index){

this.index = index;

notifyAllStudent();

}

public void notifyAllStudent(){

for (Student stu:students) {

stu.doHomeWork(index);

}

}

}

//学生类

public class Student extends DoWork {

public Student(Teacher teacher){

this.teacher = teacher;

this.teacher.attach(this);

}

@Override

void doHomeWork(int i) {

System.out.println(this+“:做作业”+i);

}

}

//使用

Teacher teacher = new Teacher();

new Student(teacher);

new Student(teacher);

new Student(teacher);

teacher.dispatchHomeWork(1);

teacher.dispatchHomeWork(3);

这个很好实,关键代码就是通过一个ArrayList保存观察着。

其实在java中,jdk已经实现好的观察者模式。点开源码就会发现他保存的是个向量

public class Observable {

private boolean changed = false;

private Vector obs;

}

17、状态模式(State Pattern)

目的:对象依赖一个状态,对象可以根据状态改变自己的行为

优点:状态转换与逻辑合在一起,而不是通过if语句隔开

缺点:会使结构比较复杂,也会增加类的个数

实现:

//状态接口

public interface State {

void doAction(MediaPlayer activity);

}

//开始状态

public class OnStart implements State{

@Override

public void doAction(MediaPlayer activity) {

System.out.println(activity+“:OnStart”);

}

}

//结束状态

public class OnStop implements State{

@Override

public void doAction(MediaPlayer activity) {

System.out.println(activity+“:OnStop”);

}

}

//播放器

public class MediaPlayer {

State state;

public void setState(State state){

this.state = state;

}

public State getState() {

return state;

}

}

//使用

MediaPlayer activity = new MediaPlayer();

OnStart onStart = new OnStart();

onStart.doAction(activity);

OnStop onStop = new OnStop();

onStop.doAction(activity);

定义了两个状态,开始和结束,让播放器 依赖这两个状态进行操作。

在android中,就比如播放器,依赖自身的状态,进行播放暂停操作。再比如Fragment,Fragment走自己的onCreate等方法,也是依赖Activity的生命周期状态进行操作。

18、责任链模式(Chain of Responsibility Pattern)

目的:主要用来解耦,客户只要把消息发到责任链上,无需关注请求细节和传递过程

优点:解耦,简化操作

缺点:性能会有一点影响,调试不太方便

实现:

//责任链接口

public interface Interceptor {

String chain(String inData);

}

//缓存

public class CacheInterceptor implements Interceptor {

@Override

public String chain(String inData) {

return inData += “加了缓存”;

}

}

//呼叫服务器

public class CallServerInterceptor implements Interceptor{

@Override

public String chain(String inData) {

return inData += “呼叫了服务器”;

}

}

//把责任 集合起来

public class RealInterceptor {

List list = new ArrayList<>();

public RealInterceptor(){

list.add(new CacheInterceptor());

list.add(new CallServerInterceptor());

}

public String request(String st){

String result = “”;

for (int i=0;i<list.size();i++){

result += list.get(i).chain(st);

}

return result;

}

}

//使用

RealInterceptor realInterceptor = new RealInterceptor();

String result = realInterceptor.request(“请求->”);

System.out.println(result);

责任链就是想链条一样,也可以在中间增加或减少,像"击鼓传花",一个个传递。

在android中,事件分发机制,父View接到事件,传递给子View。在第三方库okhttp中一个网络请求用的也是拦截器模式。

19、备忘录模式(Memento Pattern)

目的:不破坏封装的前提下,捕获一个对象的内部状态,并保存,之后能根据状态恢复到原来的样子

优点:提供了一种可以恢复的机制,封装了信息,用户不需要过多关心细节

缺点:消耗资源,如果保存内容过多过大,会占用很多资源

实现:

//Layer表示 一层

public class Layer {

private String state;

public Layer(String state) {

this.state = state;

}

public String getState() {

return state;

}

public void setState(String state) {

this.state = state;

}

}

//管理 层

public class Manager {

private Layer mLayer;

public Layer save(String state){

return new Layer(state);

}

public void restore(Layer layer){

mLayer = layer;

}

public Layer getmLayer() {

return mLayer;

}

}

//正真用这个层

public class PhotoShop {

private List layerList = new ArrayList<>();

public void ctrl_S(Layer mLayer){

layerList.add(mLayer);

}

public Layer ctrl_Z(int index){

return layerList.get(index);

}

}

//使用

PhotoShop ps = new PhotoShop();

Manager manager = new Manager();

ps.ctrl_S(manager.save(“第一层”));

ps.ctrl_S(manager.save(“第二层”));

manager.restore(ps.ctrl_Z(1));

System.out.println(“当前是:”+manager.getmLayer().getState() );

ps.ctrl_S(manager.save(“第三层”));

ps.ctrl_S(manager.save(“第四层”));

manager.restore(ps.ctrl_Z(3));

System.out.println(“当前是:”+ manager.getmLayer().getState());

就像Ps一样,Ctrl+S 保存一层,Ctrl+Z回退一层。就像玩游戏的存档一样

在android中,Activity的onSaveInstanceState保存数据在onCreate里 恢复数据

20、迭代器模式(Iterator Pattern)

目的:遍历一个对象

优点:访问一个聚合数据,聚合数据不会暴露内部内容

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

image

ps.ctrl_Z(3));

System.out.println(“当前是:”+ manager.getmLayer().getState());

就像Ps一样,Ctrl+S 保存一层,Ctrl+Z回退一层。就像玩游戏的存档一样

在android中,Activity的onSaveInstanceState保存数据在onCreate里 恢复数据

20、迭代器模式(Iterator Pattern)

目的:遍历一个对象

优点:访问一个聚合数据,聚合数据不会暴露内部内容

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-Gm2wxTVw-1711822336707)]
[外链图片转存中…(img-mApYQNGp-1711822336707)]
[外链图片转存中…(img-ZbGdgX65-1711822336708)]
[外链图片转存中…(img-af7FGo3t-1711822336708)]
[外链图片转存中…(img-Llsoisn5-1711822336709)]
[外链图片转存中…(img-SffmNh7U-1711822336709)]
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-s5YY3SXI-1711822336709)]

最后

针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

[外链图片转存中…(img-cVOPtkLA-1711822336710)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值