immutable模式详解(immutable解决哪些问题)

技术Immutable集合的示例分析这篇文章主要为大家展示了“Immutable集合的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Immutable集合的示例分析”

本文主要给大家展示“不变集的实例分析”,简单易懂,条理清晰,希望能帮你解惑。让边肖带领大家学习和研究文章《不变集的实例分析》。

不可变集合,顾名思义,意味着集合不能被修改。集合的数据项是在创建时提供的,不能在整个生命周期中更改。

为什么使用不可变对象?不可变对象有以下优点:

对于不可靠的客户代码库,在不可信的类库中使用这些对象是安全的。

线程安全:不可变对象在多线程下是安全的,没有竞争条件。

不需要支持可变性,可以尽可能节省空间和时间。不可变集的所有实现都比可变集更有效地使用内存(分析)

可以作为常数使用,预计未来保持不变。

不可变对象自然可以用作常量,因为它们本身就是不可变的。对于不可变对象的应用,这是一个很好的防御性编程的技术实践。

微软。NET团队已经正式发布了不可变集合,可以通过Nuget进行添加,包括以下不可变集合:

系统。集合。不可变的。不变的光线

系统。集合。不可变的。不可改变的数组

系统。集合。不可变的。不可改变的

系统。集合。不可变。不可改变的预测键,值

系统。集合。不可变的。不变的

系统。集合。不可变的。不变的

系统。集合。不可变的。不变的列表

系统。集合。不可变的。不可改变的

系统。集合。不可变的。不变的

系统。集合。不可变的。不变的

系统。集合。不可变的。不变的

系统。集合。不可变的。不变的。可变的。可变的。可变的。可变的

系统。集合。不可变的。不变的

系统。集合。不可变的。不可改变的

系统。集合。不可变的。不可改变的

系统。集合。不可变的。不可改变的

MSDN的文献参考号是https://msdn . Microsoft.com/有用-cn/library/system . collections . incorporated . aspx,怎么用?我们来看一个例子。假设您已经建立了计费系统。您需要一个不可变的设计,并且在多线程操作的情况下不需要担心数据损坏。例如,您需要通过工作线程打印数据的快照,这避免了阻止用户的编辑操作,并允许用户在不影响打印的情况下继续编辑。

可变数据模型如下:

班级秩序

{

公共秩序()

{

line=new ListOrderLine();

}

公共列表行{ get私有集;}

}

类订单行

{

public int Quantity { get设置;}

公共十进制单价{ get设置;}

公共浮动折扣{ get设置;}

公共十进制合计

{

得到

{

退货数量*单价*(十进制)(1.0f -折扣);

}

}

}

让我们把它变成一个不可改变的设计:

类订单行

{

> public OrderLine(int quantity, decimal unitPrice, float discount)
{
Quantity = quantity;
UnitPrice = unitPrice;
Discount = discount;
}

public int Quantity { get; private set; }

public decimal UnitPrice { get; private set; }

public float Discount { get; private set; }

public decimal Total
{
get
{
return Quantity * UnitPrice * (decimal) (1.0f - Discount);
}
}
}

这种新设计要求您创建一个订单,每当任何属性值变化创建一个新实例。您可以通过添加 WithXxx 方法,使您可以更新单个属性而无需显式调用构造函数:

class OrderLine
{
// ...

public OrderLine WithQuantity(int value)
{
return value == Quantity
? this
: new OrderLine(value, UnitPrice, Discount);
}

public OrderLine WithUnitPrice(decimal value)
{
return value == UnitPrice
? this
: new OrderLine(Quantity, value, Discount);
}

public OrderLine WithDiscount(float value)
{
return value == Discount
? this
: new OrderLine(Quantity, UnitPrice, value);
}
}

这使得不可变使用起来比较简单:

OrderLine apple = new OrderLine(quantity: 1, unitPrice: 2.5m, discount: 0.0f);

OrderLine discountedAppled = apple.WithDiscount(.3f);

现在让我们看看我们如何落实订单的不变性。Lines 属性已经是只读的但它指的是可变对象。因为它是一个集合,它可以容易地通过简单地将它替换 ImmutableList <T>转换:

class Order
{
public Order(IEnumerable<OrderLine> lines)
{
Lines = lines.ToImmutableList();
}

public ImmutableList<OrderLine> Lines { get; private set; }

public Order WithLines(IEnumerable<OrderLine> value)
{
return Object.ReferenceEquals(Lines, value)
? this
: new Order(value);
}
}

这种设计有一些有趣的属性:

• 该构造函数接受 IEnumerable <T>,允许传递任何集合中。

• 我们使用 ToImmutableList() 扩展方法,将转换为 ImmutableList <OrderLine>。如果该实例已经是不可变的列表,它会简单地转换而不是创建一个新的集合。

• 该 WithLines() 方法遵循 我们的订单公约,如果新的列表和当前列表是相同的就可以避免创建一个新的实例。

我们还可以加一些便利的方法来使它更易于更新订单行:

class Order
{
//...

public Order AddLine(OrderLine value)
{
return WithLines(Lines.Add(value));
}

public Order RemoveLine(OrderLine value)
{
return WithLines(Lines.Remove(value));
}

public Order ReplaceLine(OrderLine oldValue, OrderLine newValue)
{
return oldValue == newValue
? this
: WithLines(Lines.Replace(oldValue, newValue));
}
}

增补订单的代码看起来是这样子:

OrderLine apple = new OrderLine(quantity: 1, unitPrice: 2.5m, discount: 0.0f);
Order order = new Order(ImmutableList.Create(apple));

OrderLine discountedApple = apple.WithDiscount(discount);
Order discountedOrder = order.ReplaceLine(apple, discountedApple);

这种设计的好处是,它尽可能避免了不必要的对象创建。例如,当折扣的值等于 0.0 f,即时没有折扣,,discountedApple 和 discountedOrder 引用现有实例的苹果和订单。

这是因为:

1.apple.WithDiscount() 将返回苹果的现有实例,因为新的折扣是相同折扣属性的当前值。

2.order.ReplaceLine() 如果两个参数都相同,将返回现有实例。

我们不变的集合其他操作遵循这种最大化重用。例如,将订单行添加到 1000 的订单行的订单与 1,001 订单行不会创建整个的新列表。相反,它将重用现有列表一大块。这是可能的因为列表内部结构是为一棵树,允许共享不同实例的节点。

以上是“Immutable集合的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/148268.html

(0)

相关推荐

  • 3元一万粉抖音在线购买,抖音前期要不要刷粉?

    技术3元一万粉抖音在线购买,抖音前期要不要刷粉?抖音直播功能的上线,是广大内容创作者们的福音。虽然大多数人赶不上电商人口发展红利期,但是新的风口为我们打开了机会。
    现在要论移动互联网哪种形式抢占用户时间最多?当然要归短视

    测评 2021年11月9日
  • 有哪些Java GC的相关问题

    技术有哪些Java GC的相关问题这篇文章主要介绍“有哪些Java GC的相关问题”,在日常操作中,相信很多人在有哪些Java GC的相关问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

    攻略 2021年11月2日
  • vuejs服务器安装教程学习(vue.js下载和引入的基本步骤)

    技术vue.js的安装方式有哪些这篇文章主要介绍了vue.js的安装方式有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

    攻略 2021年12月20日
  • 字母顺序,bpmf拼音26个字母顺序

    技术字母顺序,bpmf拼音26个字母顺序声母 b p m f d t n l g k h j q x zh ch sh r z c s y w 韵母 a o

    生活 2021年10月23日
  • 正三棱柱的性质,什么叫直三棱柱,什么叫正三棱柱

    技术正三棱柱的性质,什么叫直三棱柱,什么叫正三棱柱直三棱柱是各个侧面的高相等,底面是三角形,上表面和下表面平行且全等,所有的侧棱相等且相互平行且垂直于两底面的棱柱。上下表面三角形可以是任意三角形。正三棱柱是直三棱柱的特殊

    生活 2021年10月30日
  • 如何解决红杉离线备份的相关问题

    技术Sequoiadb backupOffline相关问题怎么解决这篇文章主要介绍“Sequoiadb backupOffline相关问题怎么解决”,在日常操作中,相信很多人在Sequoiadb backupOfflin

    攻略 2021年12月22日