惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
WordPress大学
WordPress大学
U
Unit 42
I
InfoQ
A
About on SuperTechFans
宝玉的分享
宝玉的分享
J
Java Code Geeks
博客园 - 司徒正美
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
腾讯CDC
Recent Announcements
Recent Announcements

博客园 - 青玄鸟

.NET 中优雅处理 Server-Sent Events 请求取消 vue3.0 + ts 实现上传工厂(oss与cos) Dapr 订阅者参数无法正确反序列化问题 .NET 代码整洁手册 Blazor项目通过docker和nginx部署为静态站点的步骤 Moq mock 方法返回null空指针异常 基于接口隔离原则的依赖注入实现 HttpClient with Stream HttpClient partial update HttpClient 基本使用 只读集合类型属性实现 适配器模式 模板模式 最少知识原则 单例模式 抽象工厂 简单工厂、工厂方法、抽象工厂 工厂方法模式 使用 Visual Studio Code创建和执行T-SQL
值对象的封装
青玄鸟 · 2020-04-12 · via 博客园 - 青玄鸟

为什么需要封装

值对象的属性需要同时满足某些条件保证值对象数据的一致性,这些属性同时被传递(作为参数)

示例

很多场景下都会用到的开始、结束时间,两个时间必须不能为空,而且这两个时间一般同时做为参数传递

将这两个属性放到一个值对象中,让它们同时变化与维护自身逻辑,与系统其它部分解耦

代码实现

    public class DateTimeRange
    {
        public DateTime Start { get; private set; }
        public DateTime End { get; private set; }

        public DateTimeRange(DateTime start, DateTime end)
        {
            Start = start;
            End = end;
        }

        public DateTimeRange(DateTime start, TimeSpan duration)
        {
            Start = start;
            End = start.Add(duration);
        }
        protected DateTimeRange() { }

        public int DurationInMinutes()
        {
            return (End - Start).Minutes;
        }

        public DateTimeRange NewEnd(DateTime newEnd)
        {
            return new DateTimeRange(this.Start, newEnd);
        }
        public DateTimeRange NewDuration(TimeSpan newDuration)
        {
            return new DateTimeRange(this.Start, newDuration);
        }
        public DateTimeRange NewStart(DateTime newStart)
        {
            return new DateTimeRange(newStart, this.End);
        }

        public static DateTimeRange CreateOneDayRange(DateTime day)
        {
            return new DateTimeRange(day, day.AddDays(1));
        }

        public static DateTimeRange CreateOneWeekRange(DateTime startDay)
        {
            return new DateTimeRange(startDay, startDay.AddDays(7));
        }

        public bool Overlaps(DateTimeRange dateTimeRange)
        {
            return this.Start < dateTimeRange.End && 
                this.End > dateTimeRange.Start;
        }
    }

当我们审查一个实体的属性时,可能会发现有些属性总是同时出现,这时应该用一个值对象封装这些属性,让它们独立变化,不影响系统的其他部分。这也让该实体的职责更加单一。