标记字段

代码中有时候有这种需求:需要一个公共访问的标记字段,以下称为标记字段。

下面是案例:

一个订单详情页面,如果页面在显示中,程序中其它地方需要访问这个“正在查看中”的订单信息,订单详情页面打开和关闭时负责设置和清除公共字段所标记的订单对象。在像Android这样的设备上,假设页面可以打开多个,但是用户只会看到最上面的一个,那么此时只有处在任务栈最上面的OrderDetailActivity对象在其onStart和onStop中负责标记的订单的设置。假设有1和2两个详情页面依次被打开,然后依次关闭2、1,其onStart、onStop的执行顺序可能是像下面的:

09-26 11:55:10.808 5493-5493/? D/hxwcc: onStart + @1
09-26 11:55:14.840 5493-5493/? D/hxwcc: onStart + @2
09-26 11:55:15.228 5493-5493/? D/hxwcc: onStop + @1
09-26 11:55:16.672 5493-5493/? D/hxwcc: onStart + @1
09-26 11:55:17.076 5493-5493/? D/hxwcc: onStop + @2
09-26 11:55:19.548 5493-5493/? D/hxwcc: onStop + @1

可见onStart和onStop的执行是有交叉的。在对标记字段进行赋值时,需要考虑这种“相互干扰”,这里的执行都是在UI线程中执行,多线程环境下当然更容易产生这样的交叉赋值。从需求上看,不是当前对象设置的标记它就不应该去清除,因为另一个对象在重新设置标记字段的值得时候自动清除了上一标记值。

可以使用一个额外的字段记录对标记进行赋值的对象,然后通过比较当前对象标记试图操作的对象和之前设置已有标记值的对象就可以得到需要的标记作用。

下面设计一个类型FlagField来组合标记值和标记人,使得标记字段的含义更加内聚。

FlagField类型

代码如下:

/**
* 标记字段,用来存储被公共访问的带有赋值者信息的数据。赋值者在合适的时间赋值,
* 之后可以清除标记值,如果中间有其它
* 赋值者重新标记则清除操作不做任何动作——访问者继续 访问新的标记。
*/
public class FlagField<T> {
private T field;
private Object provider; public void mark(T field, Object provider) {
synchronized (this) {
this.field = field;
this.provider = provider;
}
} public T getField() {
synchronized (this) {
return this.field;
}
} public Object getProvider() {
synchronized (this) {
return this.provider;
}
} public boolean isMarked() {
synchronized (this) {
return field != null;
}
} public void clear(Object provider) {
synchronized (this) {
if (provider == this.provider) {
field = null;
provider = null;
}
}
}
}

上面提供了线程安全的版本,如果不需要多线程控制去掉synchronized (this)即可。

使用案例如下:

public class OrderDetailActivity extends Activity {
/** 当前正在被查看的订单id */
public static FlagField<Integer> viewingOrderId = new FlagField<Integer>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewingOrderId.mark(10086, this);
} @Override
protected void onDestroy() {
super.onDestroy();
viewingOrderId.clear(this);
}
}

(本文是由Atom编写)

[DS] 标记字段的更多相关文章

  1. RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers的双语版

    RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers英文版 ...

  2. 关于Differentiated Services Field (DS Field)的诸多疑问

    Differentiated Services Field (DS Field) 先上疑问截图: 这是用wireshark抓包时协议树的某一项的展开结果:IPV4 header.其中有一项如下: 大家 ...

  3. 【JPA】字段访问、属性访问及混合访问

    [JPA]字段访问.属性访问及混合访问 转载:https://www.cnblogs.com/yangchongxing/p/10120318.html 1.字段访问 注解字段,通过反射来获得和设置字 ...

  4. Discuz! X3 数据表、数据字段说明

    pre_common_admincp_cmenu 后台菜单收藏表 字段名 数据类型 默认值 允许非空 自动递增 备注 id smallint(6) unsigned    NO 是   title v ...

  5. CodeGen字段循环Field Loop

    CodeGen字段循环Field Loop 字段循环是一个模板文件构造,它允许迭代CodeGen拥有的有关字段的集合.这些字段定义可以来自以下两个位置之一: •如果基于从存储库结构中获取的信息生成代码 ...

  6. Container and Injection in Java

    一.Container 1.为什么使用Container 通常,瘦客户端多层应用程序很难编写,因为它们涉及处理事务和状态管理.多线程.资源池和其他复杂的低级细节的复杂代码行.基于组件和独立于平台的Ja ...

  7. haproxy参数

    https://blog.csdn.net/chengfei112233/article/details/78983026 https://www.cnblogs.com/dkblog/archive ...

  8. 《TCP/IP 详解 卷1:协议》第 5 章:Internet 协议

    IP 是 TCPIP 协议族中的核心协议.所有 TCP.UDP.ICMP.IGMP 数据都通过 IP 数据包(又称为 packet)来传输.IP 的英文名为 Internet Protocol,是互联 ...

  9. SIP穿越NAT SIP穿越防火墙-SBC

    FireWall&NAT FireWall是一种被动网络安全防卫技术,位于网络的边界.在两个网络之间运行訪问控制策略.防止外部网络对内部信息资源的非法訪问,也能够阻止特定信息从内部网络被非法输 ...

随机推荐

  1. webapi - 使用依赖注入

    本篇将要和大家分享的是webapi中如何使用依赖注入,依赖注入这个东西在接口中常用,实际工作中也用的比较频繁,因此这里分享两种在api中依赖注入的方式Ninject和Unity:由于快过年这段时间打算 ...

  2. 【XSS】延长 XSS 生命期

    XSS 的本质仍是一段脚本.和其他文档元素一样,页面关了一切都销毁.除非能将脚本蔓延到页面以外的地方,那样才能获得更长的生命力. 庆幸的是,从 DOM 诞生的那一天起,就已为我们准备了这个特殊的功能, ...

  3. Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

    作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...

  4. iOS开源项目周报0105

    由OpenDigg 出品的iOS开源项目周报第四期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. He ...

  5. 构建通用的 React 和 Node 应用

    这是一篇非常优秀的 React 教程,这篇文章对 React 组件.React Router 以及 Node 做了很好的梳理.我是 9 月份读的该文章,当时跟着教程做了一遍,收获很大.但是由于时间原因 ...

  6. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

  7. UE4新手引导入门教程

    请大家去这个地址下载:file:///D:/UE4%20Doc/虚幻4新手引导入门教程.pdf

  8. iOS之绘制虚线

    /*   ** lineFrame:     虚线的 frame   ** length:        虚线中短线的宽度   ** spacing:       虚线中短线之间的间距   ** co ...

  9. 深入理解 Android 之 View 的绘制流程

    概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...

  10. Win10命令提示符(cmd)怎么复制粘贴

    在Win10系统里右键开始菜单,选择弹出菜单里的命令提示符,如下图所示: 然后复制要粘贴的文字,例如: echo hovertree.com 把上面的文字复制后,点击命令提示符窗口,然后在命令提示符窗 ...