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)

相关推荐

  • 大数据有哪些特征

    技术大数据有哪些特征这篇文章主要为大家展示了“大数据有哪些特征”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“大数据有哪些特征”这篇文章吧。大数据有四个主要特征:1.Volum

    攻略 2021年12月13日
  • mysql自定义用户变量如何修改(mysql怎样查看自己设置的账户密码)

    技术执行Job时怎么省略输入MySQL保存密码本篇内容介绍了“执行Job时怎么省略输入MySQL保存密码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希

    攻略 2021年12月23日
  • JAVA中使用SQL语句查询 EXCEL文件数据

    技术JAVA中使用SQL语句查询 EXCEL文件数据这篇文章将为大家详细讲解有关JAVA中使用SQL语句查询 EXCEL文件数据,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了

    攻略 2021年12月2日
  • srvctl怎样添加新的监听和端口并静态注册

    技术srvctl怎样添加新的监听和端口并静态注册本篇文章给大家分享的是有关srvctl怎样添加新的监听和端口并静态注册,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来

    攻略 2021年11月30日
  • springboot怎么动态获取配置啊(springboot控制器参数默认值设置)

    技术怎么使用springboot获取控制器参数小编给大家分享一下怎么使用springboot获取控制器参数,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了

    攻略 2021年12月17日
  • 博字,博览群书的博字是什么意思

    技术博字,博览群书的博字是什么意思“博”字意思是:多,广泛博字。博览群书读音:bó lǎn qún shū
    释义:谓广泛阅读各类书籍,形容学识渊博。
    例句:爷爷一生博览群书,知识渊博,受到大家的敬佩。
    出处:唐朝令狐德棻

    生活 2021年10月25日