我应该扩展 ArrayList 以添加不为 null 的属性吗?

2023-11-23

我想将对象集合添加到 arrayList ,前提是特定属性不为空。

我正在考虑扩展 ArrayList 并在子类中实现检查。

一种替代方法是在将属性放入 Arraylist 之前检查该属性,但这意味着,如果我需要根据逻辑将对象添加到 arraylist,我将不得不将 if 检查分散在每个位置。

我想知道你对此的想法……再想一想,这是不是太过分了?


装饰者模式

我实际上建议包装ArrayList使用有据可查的装饰者图案。你只需将你的ArrayList和另外一个List委托大部分方法但添加验证逻辑的实现:

public class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{

    private final List<MyBusinessObject> target;

    public ValidatingListDecorator(List<MyBusinessObject> target) {
        this.target = target;
    }

    @Override
    public MyBusinessObject set(int index, MyBusinessObject element)
    {
        validate(element);
        return target.set(index, element);
    }

    @Override
    public boolean add(MyBusinessObject o)
    {
        validate(o);
        return target.add(o);
    }

    //few more to implement
    
}

优点:

  • 如果需要,您仍然可以访问原始列表而无需验证(但您可以限制这一点)
  • 更容易堆叠不同的验证,有选择地打开和关闭它们。
  • 推广组合优于继承正如所指出的@helios
  • 提高可测试性
  • 不会将您束缚于特定的List实现,您可以添加验证LinkedList or 休眠-支持的持久列表。你甚至可以考虑通用的Collection装饰器来验证任何集合。

实施说明

尽管实现了,但请记住,在重写时您必须记住很多方法:add(), addAll(), set(), subList()(?), ETC。

此外,您的对象必须是不可变的,否则用户可以添加/设置有效对象并随后修改它以违反合同。

良好的面向对象设计

最后我写道:

validate(element)

但请考虑:

element.validate()

这是一个更好的设计。

堆叠验证

如前所述,如果您想堆叠验证,验证单个单独类中的每个属性/方面,请考虑以下习惯用法:

public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{

    private final List<MyBusinessObject> target;

    public ValidatingListDecorator(List<MyBusinessObject> target) {
        this.target = target;
    }

    @Override
    public MyBusinessObject set(int index, MyBusinessObject element)
    {
        validate(element);
        return target.set(index, element);
    }

    protected abstract void validate(MyBusinessObject element);

}

...以及一些实现:

class FooValidatingDecorator extends ValidatingListDecorator {

    public FooValidatingDecorator(List<MyBusinessObject> target)
    {
        super(target);
    }

    @Override
    protected void validate(MyBusinessObject element)
    {
        //throw if "foo" not met
    }
}

class BarValidatingDecorator extends ValidatingListDecorator {

    public BarValidatingDecorator(List<MyBusinessObject> target)
    {
        super(target);
    }

    @Override
    protected void validate(MyBusinessObject element)
    {
        //throw if "bar" not met
    }
}

只想验证foo?

List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);

想要验证两者foo and bar?

List<MyBusinessObject> list = 
  new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该扩展 ArrayList 以添加不为 null 的属性吗? 的相关文章

随机推荐

  • 如何测量Python中代码行之间所花费的时间?

    所以在Java中 我们可以这样做如何测量函数执行所花费的时间 但在 python 中是如何完成的呢 要测量代码行之间的时间开始和结束时间 这样做的东西 import some time library starttime some time
  • 清除cin输入:cin.ignore不是一个好方法吗?

    有什么好的方法可以清除cin输入 我想cin clear and cin ignore是个好办法吗 Code void clearInput cin clear cin ignore 1000 n cin ignore std numeri
  • 我可以在非 Microsoft 内部应用程序中使用 Office UI Fabric React 吗?

    我想知道是否可以在与 SharePoint 或 Office 等 Microsoft 服务无关的公司内部应用程序中使用 Office React Fabric UI 框架 我阅读了许可证 但没有完全弄清楚我的问题 https github
  • SymPy——定义变量的域

    我正在编写一个程序来计算我的物理实验室的精确微分 我知道我可以设置实域或正域 from sympy import x y z symbol x y z positive True 我的问题是指定域例如n gt 1 是否可以 在我的输出中我得
  • 如何在多个项目之间共享单个库源

    问题如标题 有人问了类似的问题here 当时唯一的解决方法是将项目发布到本地 Maven 存储库中 这个问题在 Android Studio 0 5 中是否已修复 如某些人声称的那样 在其发行公告有一个声明说 支持模块内容根目录之外的源文件
  • Elasticsearch fielddata - 我应该使用它吗?

    给定一个索引 其中包含具有brand属性 我们需要创建一个不区分大小写的术语聚合 指数定义 请注意 使用现场数据 PUT demo products settings analysis analyzer my custom analyzer
  • 定时器与 setTimeout

    flash utils setTimeout 的文档状态 不使用此方法 请考虑 创建一个 Timer 对象 其中 指定间隔 使用 1 作为 重复计数参数 设置 计时器仅运行一次 有谁知道这样做是否有 显着 优势 当您只需要延迟 1 个调用时
  • Objective C:如何使用HTTP POST上传图像和文本?

    我已经成功创建了两种不同的方法 每种方法都可以上传图像或文本 但我在编写可以同时发布文本和图像的方法时遇到问题 这是我的新方法 效果很好 感谢 sgosha void upload NSString urlString http www e
  • 如何计算两个(或更多)矩形的并集多边形

    例如 我们有两个矩形 它们重叠 我想得到它们的并集的确切范围 计算这个的好方法是什么 这是两个重叠的矩形 假设顶点绳都是已知的 如何计算其联合多边形顶点的线 如果我有两个以上的矩形怎么办 存在一个线扫描算法计算 n 个矩形的并集面积 有关算
  • 从 pandas 数据框中的字符串列中删除 b''

    我有一个取自 SDSS 数据库的数据框 示例数据在这里 我想从中删除字符 b data class 我试过 data class data class replace b 但我没有得到结果 您正在使用字节字符串 你可能会考虑str deco
  • 您能推荐一个商业用途的地图API吗?

    我的要求是能够打印许多节点之间的路线 能够查询节点之间的距离以进行最佳可能的路线计算 并在地图上显示自定义图标 就道路和街道而言 拥有准确的地图源非常重要 我调查了开放的街道地图 但恐怕它可能不完全准确 任何有关商业库 API 的建议将不胜
  • 带参数的 jQuery 绑定和取消绑定事件

    我正在尝试将事件绑定到textbox包含参数 下面的 keep 看起来似乎应该这样做 但每次页面加载时 它都会被执行 jQuery function jQuery textbox bind click EventWithParam para
  • 拉伸背景图片CSS?

    td class style1 align center height 35 div style width 230px a class link span span a div td
  • 用于语义分割的 ImageDataGenerator

    我正在尝试使用 Keras 进行语义分割 并且在尝试加载图像时出现此错误flow from directory method Found 0 images belonging to 0 classes Found 0 images belo
  • 连接两条线段

    给定两条 2D 线段 A 和 B 如何计算连接 A 和 B 的最短 2D 线段 C 的长度 考虑两条线段 A 和 B 分别由两个点表示 线A由A1 x y A2 x y 表示 线 B 由 B1 x y B2 x y 表示 首先使用此算法检查
  • 如何迭代 JSON 结构? [复制]

    这个问题在这里已经有答案了 我有以下 JSON 结构 id 10 class child of 9 id 11 classd child of 10 如何使用 JavaScript 迭代它 var arr id 10 class child
  • 为什么 lambda 中的短路不起作用?

    为什么 linq 仍然尝试检查第二个表达式 Where t gt String IsNullOrEmpty someNullString t SomeProperty gt Convert ToDecimal someNullstring
  • 如何使用 Spring Boot 和嵌入式 Tomcat 禁用 TLSv1.0?

    我想用 spring boot 版本 1 3 3 停用 TLS 1 0 但如果 application yml 如下所示 它不起作用 ssl protocol TLSv1 2 key store E key server jks key s
  • 用于批量插入的触发触发器

    ALTER TRIGGER dbo TR O SALESMAN INS ON dbo O SALESMAN AFTER INSERT AS BEGIN SET NOCOUNT ON added to prevent extra result
  • 我应该扩展 ArrayList 以添加不为 null 的属性吗?

    我想将对象集合添加到 arrayList 前提是特定属性不为空 我正在考虑扩展 ArrayList 并在子类中实现检查 一种替代方法是在将属性放入 Arraylist 之前检查该属性 但这意味着 如果我需要根据逻辑将对象添加到 arrayl