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)

相关推荐

  • 经典Javascript正则表达式有哪些

    技术经典Javascript正则表达式有哪些本篇内容介绍了“经典Javascript正则表达式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大

    攻略 2021年11月26日
  • 抖音能刷粉吗,便宜刷抖音网站?

    技术抖音能刷粉吗,便宜刷抖音网站?首先,抖音刷粉是不违规的。这在行业内已经属于潜规则了。很多网红公司都在使用这类辅助工具。目前这类辅助工具,不违规,也不违法。可以放心使用。但是需要找到靠谱的代刷网,否则很可能被坑钱财。

    测评 2021年10月19日
  • springboot与springcloud版本对应关系是什么

    技术springboot与springcloud版本对应关系是什么今天就跟大家聊聊有关springboot与springcloud版本对应关系是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希

    攻略 2021年10月20日
  • 三相功率的计算公式,三相电动机功率计算方法

    技术三相功率的计算公式,三相电动机功率计算方法三相电动机功率三相功率的计算公式: P3=3P相=3*U相*I相*COSφ*效率=√3*U 线 *I线*COSφ*η 效率
    =1.732U线*I线*COSφ*效率
    1.三相

    2021年10月25日
  • thinkphp怎么开启api(thinkphp命令行怎么设置)

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

    攻略 2021年12月16日
  • 树莓派如何安装FTP服务器

    技术树莓派如何安装FTP服务器小编给大家分享一下树莓派如何安装FTP服务器,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!vsftpd开源的轻量级的常用ftp服务器。# Very Secure FTP D

    攻略 2021年11月20日