锈湖根源成就_锈的策略设计模式

锈湖根源成就

One of the means to achieve decoupling software modules is following Dependency Inversion Principle (DIP). In this post I want to show how to implement the Strategy Design Pattern in order to achieve Dependency Inversion. The basic idea behind Strategy is given that an algorithm, solving a particular problem, we define only skeleton of the algorithm at abstract level, but delegate specific algorithm’s implementation or some of its parts to another class or method. A client using algorithm may choose a specific implementation, while the general algorithm workflow remains the same. In other words, the abstract specification of the class does not depend on the specific implementation of the derived class, but specific implementation must adhere to the abstract specification. This is why we call it Dependency Inversion.

遵循依赖反转原理(DIP)是实现软件模块解耦的一种方法。 在这篇文章中,我想展示如何实现策略设计模式以实现依赖倒置。 策略背后的基本思想是,一种算法可以解决一个特定的问题,我们仅在抽象级别定义该算法的框架,但是将特定算法的实现或部分实现委托给另一个类或方法。 使用算法的客户端可以选择特定的实现,而常规算法的工作流程保持不变。 换句话说,类的抽象规范不依赖于派生类的特定实现,但是特定的实现必须遵循抽象规范。 这就是为什么我们称其为依赖倒置。

Let’s start by stating a simple problem. Imagine we have a key-value set (e.g. from database) and want to serialise it in different formats, e.g., in plain text as following

让我们从一个简单的问题开始。 假设我们有一个键值集(例如,来自数据库),并希望以不同的格式(例如,以纯文本格式)进行序列化

name john
age 25
occupation developer

or in json format like this

或像这样的json格式

{ 
"name": "john",
"age": 25,
"occupation": "developer"
}

A simplest approach would be implement separate classes for each format. But we don’t want to repeat code for invariant part of the algorithm for each format, especially imagine we if we had 20 or 30 different formats. We don’t either want to change the entire class (or our code base) just because we add a new output format.

最简单的方法是为每种格式实现单独的类。 但是我们不想为每种格式的算法不变部分重复代码,特别是想象我们有20或30种不同的格式。 我们都不希望仅仅因为我们添加了新的输出格式而更改了整个类(或我们的代码库)。

Alright. Let’s create a new project cargo new design_patters and create a new folder src/strategy.Inside src/strategy create a new file mod.rs.

好的。 让我们创建一个新的项目cargo new design_patters并创建一个新的文件夹src/strategy.src/strategy内部创建一个新文件mod.rs

First of all we create a struct Report holding two vectors: keys and values. For simplicity, keys are strings and values are integers.

首先,我们创建一个结构Report两个向量:键和值。 为简单起见,键是字符串,值是整数。

Next we need to define interfaces for creating a new report and generating key-value output

接下来,我们需要定义用于创建新报告和生成键值输出的接口

At this point, before we implement new, I’d like to mention a well-known technique called Dependency Injection. In our implementation we use Dependency Injection when we create a new report. We provide a strategy which will be used when we call generate on Report. However, Report struct needs somehow to store the strategy so that it could later use it when client invokes generate. So, how do we deal with this problem?

在这一点上,在我们实现new,之前new,我想提到一种称为Dependency Injection的众所周知的技术。 在我们的实现中,当我们创建新报告时,我们将使用依赖注入。 我们提供一种策略,当我们在Report上调用generate时将使用该策略。 但是, Report结构需要某种方式存储策略,以便稍后在客户端调用generate时可以使用它。 那么,我们如何处理这个问题呢?

Our approach is provide Report , when we instantiate it, with another object (instance of another struct) which is a strategy implementing some trait. In other words, we specify some rules at abstract (high) which should be followed by strategy objects.

我们的方法是在实例化时为Report提供另一个对象(另一个结构的实例),该对象是一种实现某些特征的策略。 换句话说,我们在抽象(高级)处指定了一些规则,策略对象应遵循这些规则。

We introduce a new trait Generator which has a single method run. This method expects a reference to a Report object. We also add member to Report struct, generator, of type Box<dyn Generator>. In simple words Box<dyn Generator> means any type inside a Box must implement the Generator trait. Now, let’s implement generate and new.

我们引入了一个新的特征Generator ,它可以run一个方法。 该方法需要引用Report对象。 我们还向Box<dyn Generator>.类型的Report结构generator添加成员Box<dyn Generator>. 简而言之Box<dyn Generator> 表示Box内的任何类型都必须实现Generator特征。 现在,让我们实现generatenew

When we create a new Report we provide a strategy object which must implement trait Generator invoked upon in Report’s generate method. This is where dependency injection occurs. In summary, when we create a Report we must provide key, values and a strategy object, and then call generate upon the report to get key value output. The following snippet show how to create and use Report.

当我们创建一个新的Report我们提供了一个策略对象,该对象必须实现在Reportgenerate方法中调用的特征Generator 。 这是依赖注入发生的地方。 总而言之,当我们创建Report我们必须提供键,值和策略对象,然后在报表上调用generate以获得键值输出。 以下代码段显示了如何创建和使用Report.

So, I think everything is clear except Text{}inside Box::new. Text{} is our strategy object implemented separately. Report object does not care about how Text generates key-values. Report only provides Text with raw data by passing self: self.generator.run(&self).

因此,我认为除了Box::new内的Text{}外,其他所有内容都很清晰。 Text{}是我们单独实现的策略对象。 Report对象不关心Text如何生成键值。 Report仅通过传递selfself.generator.run(&self).Text提供原始数据self.generator.run(&self).

Now that we have high level specifications defined, let’s implement our first strategy object. Create a new file src/strategy/text.rs with the following code

现在我们已经定义了高级规范,让我们实现第一个策略对象。 使用以下代码创建一个新文件src/strategy/text.rs

This is Dependency Inversion in action. Report struct does not depend on strategy object implementation, but strategy objects, as well as Report object itself, adhere to a high level abstraction. In particular, any strategy object must implement Generator trait and provide the run interface and any client using the Report must provide a strategy object, apart from data, and call generate to get output. That’s all about high level abstraction.

这是实际的依赖倒置。 Report结构不依赖于策略对象的实现,但是策略对象以及Report对象本身都遵循高级抽象。 特别是,任何策略对象都必须实现Generator特征并提供run接口,并且使用Report任何客户端都必须提供除数据之外的策略对象,并调用generate来获取输出。 这就是高层抽象。

Let’s implement another strategy for generating in json format.

让我们实现另一种以json格式生成的策略。

Create a new file src/strategy/json.rs with the following code

使用以下代码创建一个新文件src/strategy/json.rs

and use both strategy objects

并同时使用两个策略对象

Full code can be found here.

完整的代码可以在这里找到。

Thank you for reading :-)

感谢您的阅读:-)

翻译自: https://medium.com/swlh/strategy-design-pattern-in-rust-5f5486cd294c

锈湖根源成就

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值