0%

代理模式

代理模式是一种结构型设计模式, 让你能提供真实服务对象的替代品给客户端使用。 代理接收客户端的请求并进行一些处理 (访问控制和缓存等), 然后再将请求传递给服务对象。

问题

当我们的系统过有一些对象是非常缓慢和影响性能的,它可能持有了大量的系统资源或者运行在远端(服务器、其它应用)。我们需要操作它们但并不是总是需要,系统的多个地方可能都会有操作它们的需要,这会对性能造成很大的影响。

阅读全文 »

适配器模式

适配器是一种结构型设计模式, 它能使不兼容的对象能够相互合作。
适配器可担任两个对象间的封装器, 它会接收对于一个对象的调用, 并将其转换为另一个对象可识别的格式和接口。

问题

当我们使用外部的第三方库以及兼容很久以前的代码时,通常会遇到一些困扰。有可能外部的库提供的接口不兼容我们项目里已有的数据格式,我们又没有这个库的源码无法进行修改;有可能很久以前的代码因为时间很久没有人继续维护了,我们在不修改原来这块代码的同时希望能够继续使用它。

阅读全文 »

桥接模式

桥接是一种结构型设计模式, 可将业务逻辑或一个大类拆分为不同的层次结构, 从而能独立地进行开发。

问题

当一个类有多个维度的特性,如果仅通过继承的方式生成子类会生成大量的子类,还不容易对其中某个特性进行扩展,因为这会需要修改相关的大量的类。

比如一个物品有形状和颜色两个维度的特性,如果颜色有红色和蓝色,形状有方形和球形,这就对应了四个子类。如果新增一个黄色那就需要新增两个类(黄色方形、黄色球形),如果这时候形状再增加一种三角形,那么就需要再新增三个类(红色三角形, 蓝色三角形,黄色三角形)。这还只是2个维度的,如果维度更多类的数量会非常多,并且呈指数增长。

阅读全文 »

外观模式

外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。

问题

当你在程序种需要使用大量的第三方库以及框架,你会需要管理众多对象,而可能你实际需要使用的能力远没有这么多。众多不重要的对象会增加库的复杂程度,使理解和维护程序很难进行。

阅读全文 »

建造者模式

建造者模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。

问题

假设有这样一个复杂对象, 在对其进行构造时需要对诸多成员变量和嵌套对象进行繁复的初始化工作。它一般有众多需要传入的初始化参数,一般情况下绝大多数参数都没有用,只有在少数特定情况下才会使用到它们。这使得构造方法非常的不简洁。

阅读全文 »

抽象工厂模式

抽象工厂是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

问题

当你想要使你的客户端与创建的对象完全解耦,你不希望了解具体产品的细节以及它的具体实现类。同时所有的可能的产品拥有多种不同的变体形成了多个系列的产品。

阅读全文 »

简单工厂模式

简单工厂模式 描述了一个类, 它拥有一个包含大量条件语句的构建方法, 可根据方法的参数来选择对何种产品进行初始化并将其返回。它并不是《Design Patterns - Elements of Reusable Object-Oriented Software》(通用的设计模式参考书)所推荐的23种设计模式的其中之一。更像是一种书写代码的风格和习惯。下面给出代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
public class WeaponFactory {
public IWeapon produceWeapon(String name) {
if ("AK47".equals(name)) {
return new AK47();
} else if ("Tank".equals(name)) {
return new Tank();
} else if ("Missile".equals(name)) {
return new Missile();
} else {
return null;
}
}
}

完整代码地址

单例模式

单例是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

问题

当你希望控制某些共享资源、状态变量或者访问权限时,你会希望某些类的实例数量仅能为一个;或者当你希望可以在系统全局的任意位置去访问同一个实例。

阅读全文 »

原型模式

原型模式属于创建型设计模式。基于一个已创建的原型对象,以拷贝的方式快速创建其它对象。

问题

当你想创建一个一模一样或者仅仅有一点区别的对象,你可能没有这个对象真正的实现类或者没有这个对象创建过程所经历的过程。

阅读全文 »

Duplicate class error,Android support和Androidx库共存的问题

这两天正好遇到这样一个问题,公司项目在引入新的aar库时出现了下面这个错误。除此之外还有一个AndroidManifest.xml文件merge error。

1
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules classes.jar

在网上查了下资料,大概了解是因为新引入的包使用的android.support包,而我们的项目工程已经整体迁移到androidx,这两个库在功能上是重叠的,所以导致了上述的报错。

针对这种情况android官方提供了一种方式。在项目根目录下的gradle.properties文件中加入这两行。

1
2
android.useAndroidX=true//是否使用androidx	
android.enableJetifier=true//是否将引入的第三方库中的android.support强制转为androidx

加入这两行后可以解决大部分上述问题。

但是公司项目在此次引入库(称做B.aar,B.aar使用了普通的android.support)之前是将”android.enableJetifier”开关注释了,原因是项目中原本使用的一个第三方库,这个库对android.support库做了定制(称做A.aar,A.aar使用了自己定制的android.support)。如果使用了“android.enableJetifier”开关,会改变所有“android.support.XX”包名为”androidx.XX”,这会导致A.aar的功能不可用。

由此出现一种局面就是:1.如果我们将“android.enableJetifier”置为true会因为改变了定制过的android.support库而使A.aar不可用;2.如果我们将“android.enableJetifier”置为false会因为项目项目本身使用的androidX和B.aar当中的普通android.support产生support库的冲突。

我们希望能够将B.aar当中的普通android.support强制转换为androidx,却又不想A.aar当中的定制android.support库被强转为androidx,经过多方了解和尝试我们找到Android官网没有写明的一个配置项,可以忽略某个包下面的强转,如下所示:

1
2
3
android.useAndroidX=true//是否使用androidx	
android.enableJetifier=true//是否将引入的第三方库中的android.support强制转为androidx
android.jetifier.blacklist=A.aar

这样就完美解决了这个问题。