Android进阶之光——设计模式(结构型设计模式)
2021-08-28 本文已影响0人
So_ProbuING
结构型设计模式
结构型设计模式是从程序的结构上解决模块之间的耦合问题
代理模式
代理模式也被称为委托模式。
-
定义:为其他对象提供一种代理以控制这个对象的访问
代理模式结构图
代理模式中有如下角色:
- Subject:抽象主题类,声明真实主题与代理的共同接口方法
- RealSubject:真实主题类,代理类所代表的真实主题。客户端通过代理类间接地调用真实主题类的方法
- Proxy:代理类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行
- Client:客户端类
代理模式的简单实现
- 抽象主题类
interface IShop{
void buy();
}
- 真实主题类
class meWx implements IShop {
@Override
public void buy() {
System.out.println("wxBuy");
}
}
- 代理类
class Purchasing implements IShop{
private IShop iShop;
public Purchasing(IShop iShop) {
this.iShop = iShop;
}
@Override
public void buy() {
iShop.buy();
}
}
- 客户端类
public class ProxyType {
public static void main(String[] args) {
meWx meWx = new meWx();
Purchasing purchasing = new Purchasing(meWx);
purchasing.buy();
}
}
动态代理的简单实现
代理模式分为静态代理和动态代理,
静态代理在代码运行前就已经存在了代理类的class编译文件。
动态代理则是在代码运行时通过反射来动态地生成代理对象,并确定到底来代理谁。
我们将上面的例子做一下修改,创建动态代理类
IShop iShop = new meWx();
DynamicPurchasing dynamicPurchasing = new DynamicPurchasing(iShop);
ClassLoader classLoader = iShop.getClass().getClassLoader();
IShop purchasing = (IShop) Proxy.newProxyInstance(classLoader, new Class[]{IShop.class}, dynamicPurchasing);
purchasing.buy();
装饰模式
装饰模式,其在不必改变类文件和使用继承的情况下,动态地扩展一个对象的功能。是继承的替代方案之一。它通过创建一个包装对象,也就是装饰类包裹真实的对象
-
定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活
装饰模式的结构图 - Component:抽象组件,可以是接口或是抽象类,被装饰的最原始的对象
- ConcreteComponent:组件具体实现类。被装饰的具体对象
- Decorator:抽象装饰者。从外类来拓展Component类的功能
- ConcreteDecorator:装饰者的具体实现类
装饰的简单实现
- 抽象组件
abstract class Swordsman{
abstract void attackMagic();
}
- 组件具体实现类
class YangGuo extends Swordsman{
@Override
void attackMagic() {
System.out.println("杨过会全真剑法");
}
}
- 抽象装饰者
抽象装饰者保持了一个对抽象组件的引用,方便调用被装饰对象中的方法。
abstract class Master extends Swordsman{
private Swordsman swordsman;
public Master(Swordsman swordsman) {
this.swordsman = swordsman;
}
@Override
void attackMagic() {
swordsman.attackMagic();
}
}
- 装饰者具体实现
class HongQiGong extends Master{
public HongQiGong(Swordsman swordsman) {
super(swordsman);
}
public void teachAttackMagic(){
System.out.println("教杨过打狗棒法");
}
@Override
void attackMagic() {
super.attackMagic();
teachAttackMagic();
}
}
- 客户端
···
public static void main(String[] args) {
YangGuo yangGuo = new YangGuo();
HongQiGong hongQiGong = new HongQiGong(yangGuo);
hongQiGong.attackMagic();
}
···
外观模式
外观模式也被称为门面模式。它通过一个外观类使得整个系统的结构只有一个统一的高层接口,可以降低用户的使用成本
-
定义:要求一个子系统的外部与内部的通信必须通过一个统一的对象进行。此模式提供一个高层的接口,使得子系统更易于使用
外观模式的结构图
外观模式有如下角色:
- Facade:外观类,知道哪些子系统类负责处理请求,将客户端的请求代理给适当的子系统
- SubSystem:子系统类,可以有一个或多个子系统,实现子系统的功能,处理外观类指派的任务,注意子系统类不含有外观类的引用
外观模式的简单实现
- 子系统类
class ZhaoShi{
public void TaiJiQuan(){
System.out.println("太极拳");
}
public void QiShangQuan(){
System.out.println("七伤拳");
}
public void ShengHuo(){
System.out.println("圣火令");
}
}
class NeiGong{
public void JiuYang() {
System.out.println("九阳神功");
}
public void QianKun(){
System.out.println("乾坤大挪移");
}
}
- 外观类
class ZhangWuJi{
private ZhaoShi zhaoShi;
private NeiGong neiGong;
public ZhangWuJi() {
zhaoShi = new ZhaoShi();
neiGong = new NeiGong();
}
public void qianKun(){
neiGong.QianKun();
}
}
- 客户端调用
public static void main(String[] args) {
ZhangWuJi zhangWuJi = new ZhangWuJi();
zhangWuJi.qianKun();
}
享元模式
享元模式可以减少应用程序创建的对象,降低程序内存的占用,提高性能
-
定义:使用共享对象有效地支持大量细粒度的对象
享元模式结构图 -
Flyweight:抽象享元角色,同时定义出对象的外部状态和内部状态的接口或者实现
-
ConcreteFlyweight:具体享元角色,实现抽象享元角色定义的业务
-
FlyweightFactory:享元工厂,负责管理对象池和创建享元对象
享元模式的简单实现
- 抽象享元角色
interface IGoods{
public void showGoodsPrice(String name);
}
- 具体享元角色
class Goods implements IGoods{
private String name;
private String version;
public Goods(String name) {
this.name = name;
}
@Override
public void showGoodsPrice(String name) {
if (version.equals("32G")) {
System.out.println("5199yuan");
}
}
}
- 享元工厂
class GoodsFactory{
private static Map<String,Goods> pool = new HashMap<String,Goods>();
public static Goods getGoods(String name){
if (pool.containsKey(name)) {
System.out.println("使用缓存,key为" + name);
return pool.get(name);
}else {
Goods goods = new Goods(name);
pool.put(name, goods);
System.out.println("创建商品,key为" + name);
return goods;
}
}
}
- 客户端调用
public static void main(String[] args) {
Goods iphone7 = GoodsFactory.getGoods("iphone7");
iphone7.showGoodsPrice("32G");
}