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)

相关推荐

  • C语言怎么实现内存对齐

    技术C语言怎么实现内存对齐这篇文章主要讲解了“C语言怎么实现内存对齐”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言怎么实现内存对齐”吧!  一、概念      

    攻略 2021年12月8日
  • 21.Oracle权限详解

    技术21.Oracle权限详解 21.Oracle权限详解Oracle权限管理详解 Oracle 权限权限允许用户访问属于其它用户的对象或执行程序,ORACLE系统提供三种权限:Object 对象级、S

    礼包 2021年12月7日
  • 做某事有困难英语,英文做某事有困难还有哪些表达

    技术做某事有困难英语,英文做某事有困难还有哪些表达1做某事有困难英语、have a problem(in) doing sth释义:做某事有困难
    例句:But the states dont have a problem

    生活 2021年10月24日
  • Redis与数据库数据一致性的示例分析

    技术Redis与数据库数据一致性的示例分析这期内容当中小编将会给大家带来有关Redis与数据库数据一致性的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 可能谈到保持R

    攻略 2021年12月1日
  • 老公英文怎么写简称,NBA各球队的英文和简称怎么写

    技术老公英文怎么写简称,NBA各球队的英文和简称怎么写大 西 洋 赛 区Boston Celtics波士顿凯尔特人
    New Jersey Nets
    新泽西网
    New York Knicks
    纽约尼克斯
    Philadelp

    生活 2021年10月23日
  • 离子方程式中不能拆的物质,pbso4离子方程式能拆吗

    技术离子方程式中不能拆的物质,pbso4离子方程式能拆吗把易溶于水易电离的物质化学式改成离子哪些化学式要写成离子即能拆?哪些化学式不能写成离子即不能拆?要改写成离子的物质离子方程式中不能拆的物质:易溶于水的强电解质,包括

    生活 2021年10月28日