您的位置:首页 > 科技 > IT业 > 网站建站基本要素_中国平安财产保险公司官网_如何免费搭建自己的网站_seo推荐

网站建站基本要素_中国平安财产保险公司官网_如何免费搭建自己的网站_seo推荐

2024/12/23 12:17:16 来源:https://blog.csdn.net/Patrick_yuxuan/article/details/144333737  浏览:    关键词:网站建站基本要素_中国平安财产保险公司官网_如何免费搭建自己的网站_seo推荐
网站建站基本要素_中国平安财产保险公司官网_如何免费搭建自己的网站_seo推荐

文章目录

  • 代理模式
    • 示例
    • 结构
    • 分类
    • 动态代理
  • 装饰模式
    • 示例
    • 结构
    • 使用场景
    • 与代理模式区别
    • Context
  • 外观模式
    • 结构
    • 示例
    • 使用场景
    • Context
  • 享元模式
    • 结构
    • 示例
    • 使用场景
    • Message

代理模式

代理模式(Proxy Pattern) 是一种结构型设计模式,它提供了一个代理对象,控制对目标对象的访问。代理对象通常在客户端与目标对象之间起到中介的作用,用于扩展目标对象的功能。

定义:为其他对象提供一种代理以控制对这个对象的访问

示例

定义接口

// 公共接口
public interface IShop {void buy();
}

实现真实类

// 真实对象
public class Buyer implements IShop{@Overridepublic void buy() {System.out.println("购买");}
}

定义代理类

// 代理类
public class Buying implements IShop{private IShop iShop;public Buying(IShop iShop) {this.iShop = iShop;}@Overridepublic void buy() {iShop.buy();}
}

测试代码

public class Client {public static void main(String[] args) {// 创建真实对象IShop person1 = new Buyer();// 创建代理对象IShop proxy = new Buying(person1);// 使用代理对象proxy.buy();}
}

结构

Subject(抽象主题):定义目标对象和代理对象的公共接口。

RealSubject(真实主题):实现了Subject接口,定义了具体的业务逻辑。

Proxy(代理):代理对象,包含对真实主题的引用,并且可以在对真实主题的调用前后添加额外的功能。

1733493914683

分类

  1. 静态代理

静态代理是指在编译时就已经确定代理类的实现,通常是手动编写代理类。静态代理的关键特点是代理类与目标类之间有一一对应的关系。

  1. 动态代理

动态代理是在运行时动态生成代理对象,而不是在编译时就明确写好的。Java提供了通过反射机制动态的生成代理对象的机制

动态代理

java提供了java.lang.reflect.InvocationHandler,一个便捷的动态代理接口,实现它要重写其调用方法invoke

// 目标接口
public interface Subject {void request();
}// 目标类
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("真实主题:处理请求。");}
}// 动态代理的处理器
public class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理:在真实主题处理请求之前。");Object result = method.invoke(target, args);  // 调用目标方法System.out.println("代理:在真实主题处理请求之后。");return result;}
}// 测试
public class DynamicProxyDemo {public static void main(String[] args) {// 创建一个真实的目标对象RealSubject realSubject = new RealSubject();// 使用Proxy创建代理对象Subject proxy = (Subject) Proxy.newProxyInstance(// 目标类的类加载器realSubject.getClass().getClassLoader(),// 目标类实现的接口new Class[] {Subject.class},  // 代理的处理器(即动态代理的逻辑)new DynamicProxyHandler(realSubject));// 调用代理对象的方法proxy.request();}
}

装饰模式

定义

动态地向对象添加额外的职责,而不改变其结构。

使用场景

需要透明且动态地扩展类的功能时

示例

// 抽象组件类
public abstract class Component {// 抽象操作方法,由子类实现public abstract void operate();
}
// 具体组件类
public class ConcreteComponent extends Component {@Overridepublic void operate() {System.out.println("执行基本操作");}
}
// 装饰者基类
public abstract class Decorator extends Component {protected Component component; // 持有组件对象的引用public Decorator(Component component) {this.component = component;}@Overridepublic void operate() {component.operate(); // 调用组件的操作}
}
// 具体装饰者实现类
public class ConcreteDecoratorA extends Decorator {public LoggingDecorator(Component component) {super(component);}@Overridepublic void operate() {System.out.println("开始");super.operate(); // 调用原始操作System.out.println("结束");}
}
public class DecoratorPatternDemo {public static void main(String[] args) {// 创建具体组件Component component = new ConcreteComponent();// 根据组件对象构造装饰者componentA并调用Component componentA = new ConcreteDecoratorA(component);componentA.operate();}
}

1733658580628

结构

  1. 抽象组件(Component): 一个接口或抽象类,被装饰的原始对象
  2. 具体组件(ConcreteComponent): 抽象组件的具体实现,是被装饰的核心对象
  3. 抽象装饰者(Decorator): 抽象类或接口,持有一个组件对象的引用,并定义与组件一致的接口
  4. 具体装饰者(ConcreteDecorator): 抽象装饰者实现类,对抽象装饰者做出具体的实现

使用场景

  1. 动态扩展一个类的功能。
  2. 替代多层次的继承结构。
  3. 当不能直接修改类或不希望影响其他对象时。

与代理模式区别

装饰模式

  • 目的:装饰模式用于动态地扩展一个对象的功能,且对客户端透明。它是继承关系的替代方案,可以通过包装原对象并为其添加新的功能,而不改变原对象的结构。
  • 使用场景:当你需要扩展对象的功能时,不希望直接修改原有的类时

代理模式

  • 目的:代理模式用于为其他对象提供一个替代品或代理对象,以便通过代理对象来控制对原对象的访问。代理对象本身不增强原对象的功能,而是控制访问、延迟加载、安全检查等。
  • 使用场景:当你希望控制对某个对象的访问(例如,延迟加载、访问权限控制、日志记录等)时,可以使用代理模式。

装饰模式强调对对象功能的增强和扩展。

代理模式关注对对象的访问控制、管理、替代。

核心区别:装饰模式是为了增强原对象的功能,而代理模式是为了控制原对象的访问。

Context

59696fbdc60c2005397adbbcf2f24f7b

// 抽象组件
public abstract class Context {public abstract void startActivity(@RequiresPermission Intent intent);public void startActivity(Intent intent, Bundle options);
}
// 具体组件实现类
class ContextImpl extends Context{@Overridepublic void startActivity(Intent intent) {warnIfCallingFromSystemProcess();startActivity(intent, null);}@Overridepublic void startActivity(Intent intent, Bundle options) {warnIfCallingFromSystemProcess();final int targetSdkVersion = getApplicationInfo().targetSdkVersion;if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0&& (targetSdkVersion < Build.VERSION_CODES.N|| targetSdkVersion >= Build.VERSION_CODES.P)&& (options == null|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {throw new AndroidRuntimeException("Calling startActivity() from outside of an Activity"+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."+ " Is this really what you want?");}mMainThread.getInstrumentation().execStartActivity(getOuterContext(), mMainThread.getApplicationThread(), null,(Activity) null, intent, -1, options);}
}
// 装饰者,持有ContextImpl的对象
public class ContextWrapper extends Context {Context mBase;@Overridepublic void startActivity(Intent intent) {mBase.startActivity(intent);}@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {mBase.startActivity(intent, options);}
}
Activity extends ContextThemeWrapper
ContextThemeWrapper extends ContextWrapper

Activity就是具体装饰者

ContextImpl的创建和ContextWrapperContextImpl引用在ActivityThreadmain函数中进行

外观模式

外观模式(Facade Pattern)是一种结构型设计模式,它为复杂的子系统提供一个简单的接口。

目的是简化系统的使用方式,使得调用者可以通过一个统一的入口来访问系统中的多个子系统,而不需要关心子系统的内部实现细节。

结构

外观模式通常包含以下几个角色:

  1. Facade(外观类):提供一个简化的接口,委托请求给子系统。

  2. Subsystem(子系统类):各个独立的子系统,完成具体的业务逻辑。

1733665652587

示例

// 外观类:简化多个功能操作的接口
class SmartphoneFacade {private Camera camera = new Camera();private MusicPlayer musicPlayer = new MusicPlayer();public void takePhotoAndPlayMusic() {camera.open();camera.takePhoto();musicPlayer.play();}public void stopMusicAndCloseCamera() {musicPlayer.stop();camera.open(); }
}// 子系统相机
class Camera {public void open() {System.out.println("打开相机");}public void takePhoto() {System.out.println("拍照");}
}
// 子系统音乐播放器类似// 客户端
public class FacadePatternExample {public static void main(String[] args) {SmartphoneFacade smartphone = new SmartphoneFacade();smartphone.takePhotoAndPlayMusic();smartphone.stopMusicAndCloseCamera();}
}

使用手机只需要调用相关方法,而不用去管CameraMusicPlayer的具体实现

使用场景

  • 当系统较为复杂时,使用外观模式可以简化与子系统的交互,提供一个更易于使用的接口。
  • 为多个子系统提供一个统一的接口。
  • 需要解耦子系统与外部代码的依赖关系。

优点

  • 简化接口:隐藏了系统的复杂性,提供了更简单的接口。
  • 降低耦合:客户端与子系统之间的耦合度降低,修改子系统的实现不会影响到客户端。

Context

Context封装了很多重要的操作,如 startActivitysendBroadcastbindService 等。因此,Context对开发者来说是最重要的高层接口。Context只是一个定义了很多接口的抽象类,这些接口的功能实现并不是在Context及其子类中,而是通过其他子系统来完成。

Context只是一个抽象类,它的真正实现在Contextlmpl类中,Contextlmpl就是外观类。

  1. startActivity()startActivity() 方法启动一个新的 Activity,但实际的启动过程是通过 ActivityManagerService 来完成的。
  2. sendBroadcast():底层的实现则是通过 BroadcastManager 来处理。
  3. bindService()bindService() 方法允许应用与服务建立连接,实际操作是通过 ServiceManager 来管理服务的绑定。

享元模式

享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象共享、避免创建过多对象的效果,可以提升性能、避免内存移除等。

核心思想是复用已经存在的对象,而不是每次都创建新对象。

享元对象中的部分状态是可以共享,可以共享的状态成为内部状态,内部状态不会随着环境变化;不可共享的状态则称为外部状态,它们会随着环境的改变而改变。

在享元模式中会建立一个对象容器,在经典的享元模式中该容器为一个 Map,它的键是享元对象的内部状态,它的值就是享元对象本身。客户端程序通过这个内部状态从享元工厂中获取享元对象,如果有缓存则使用缓存对象,否则创建一个享元对象并且存入容器中,这样一来就避免了创建过多对象的问题。

结构

  1. 抽象享元(Flyweight):定义享元对象的基类或接口
  2. 具体享元(ConcreteFlyweight):实现抽象享元对象
  3. 享元工厂(FlyweightFactory):用于管理享元对象的创建和共享,确保享元对象的复用。

示例

在火车票预订系统中,有很多用户会购买相同类型、相同时间、相同座位的火车票。每次有用户购买相同的火车票时,我们不需要为每个用户创建一个新的火车票对象,而是可以共享相同的火车票对象。享元模式可以帮助我们避免为每个用户创建重复的对象,从而节省内存。

享元对象(Flyweight)

TrainTicket 类是享元对象,表示火车票的固定信息,例如车次、出发时间、座位类型等。

// 享元类:火车票
public class TrainTicket {private String trainNumber; // 车次private String departureTime; // 出发时间// 构造方法,初始化火车票的固定信息public TrainTicket(String trainNumber, String departureTime) {this.trainNumber = trainNumber;this.departureTime = departureTime;}// 购票public void serve(String passengerName) {System.out.println("乘车人:" + passengerName + " ,车次 " + trainNumber +",发车时间: " + departureTime);}
}

享元工厂(FlyweightFactory)

TrainTicketFactory 类是享元工厂,用于管理和共享火车票对象。

public class TrainTicketFactory {private Map<String, TrainTicket> ticketMap = new HashMap<>();public TrainTicket getTrainTicket(String trainNumber, String departureTime) {String key = trainNumber + departureTime;if (!ticketMap.containsKey(key)) {ticketMap.put(key, new TrainTicket(trainNumber, departureTime));System.out.println("购票成功,乘车人:" + trainNumber + ", 车次: " + departureTime);}return ticketMap.get(key); // 返回共享的火车票对象}
}

客户端

public class TrainStation {public static void main(String[] args) {TrainTicketFactory ticketFactory = new TrainTicketFactory();TrainTicket ticket1 = ticketFactory.getTrainTicket("G101", "10:00");TrainTicket ticket2 = ticketFactory.getTrainTicket("G101", "10:00");TrainTicket ticket3 = ticketFactory.getTrainTicket("D202", "14:00");ticket1.serve("Alice");ticket2.serve("Bob");ticket3.serve("Charlie");}
}
  • TrainTicket 类是享元对象,火车票的固定信息,相同的,可以被多个乘客共享。
  • TrainTicketFactory 类是享元工厂,维护了一个火车票对象池,确保每种车次、出发时间和座位类型的火车票只创建一次。如果有相同的请求,返回已有的火车票对象。
  • TrainStation 类模拟了多个乘客购买相同车次、相同时间的火车票。由于使用了享元模式,虽然有多个乘客,但共享了相同的火车票对象。

使用场景

  1. 对象创建代价高,且每个对象的内部状态差别不大。
  2. 需要优化程序性能,减少内存消耗。

IMG_20241208_205403

Message

在Handler中,使用对象池来管理 Message 对象,能够有效避免频繁的对象创建,减少内存占用和GC频率。

public final class Message implements Parcelable {Message next;// 同步锁的对象public static final Object sPoolSync = new Object();// 对象池的头部,具体实现是链表private static Message sPool;// 当前池中存储的 Message 对象数量private static int sPoolSize = 0;// 对象池的最大容量private static final int MAX_POOL_SIZE = 50;public static Message obtain() {// 线程安全synchronized (sPoolSync) {if (sPool != null) {// 从池中取出一个 Message 对象Message m = sPool;// 更新池的头部为下一个对象sPool = m.next;// 清空当前 Message 对象的链表连接,避免不必要的引用m.next = null;// 清除消息的标志位,表示该对象已被重用m.flags = 0;// 更新池中存储的对象数量sPoolSize--;return m;}}// 如果池中没有可复用的对象,创建一个新的 Message 对象并返回return new Message();}/*** 回收该 Message 对象,准备将其放入对象池中。* 该方法会检查 Message 是否还在使用中,若仍在使用则抛出异常。*/public void recycle() {if (isInUse()) {  if (gCheckRecycle) {  throw new IllegalStateException("This message cannot be recycled because it "+ "is still in use.");}return;  }recycleUnchecked();}/*** 实际进行回收操作,将该对象状态清空,并加入对象池中以供复用。*/void recycleUnchecked() {// 清除对象的各个字段,确保该对象回收后不再持有任何引用flags = FLAG_IN_USE;what = 0;arg1 = 0;arg2 = 0;obj = null;replyTo = null;sendingUid = UID_NONE;workSourceUid = UID_NONE;when = 0;target = null;callback = null;data = null;synchronized (sPoolSync) {  if (sPoolSize < MAX_POOL_SIZE) {  next = sPool;  sPool = this;  sPoolSize++;  }}}
}

Message 类承担了三个职责:

  1. Flyweight 抽象角色:提供了统一的接口来处理对象的共享和复用。
  2. ConcreteFlyweight 具体享元角色:实际存储对象的状态并处理业务逻辑。
  3. FlyweightFactory 工厂角色:管理对象池,复用和回收 Message 对象。


参考:

  1. 《设计模式之禅》
  2. 《Android进阶之光》
  3. 《Android源码设计模式解析与实战》

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com