Event storming

https://developer.ibm.com/technologies/java/tutorials/reactive-in-practice-1/#

Reactive in practice, Unit 1: Event storming the stock trader domain

DDD事件风暴(上)——原理篇

前言

范钢老师在devops社区的系列分享第一篇-《快速交付》之设计篇,以电商中的购物环节为例,利用领域驱动设计方法来建模,介绍了事件风暴,聚合,聚合根,命令等一系列概念。作为DDD的入门者,这些概念还是比较模糊的。在IBM Developer找了一篇文章,详细介绍了DDD的基本概念和实践,翻译出来与大家分享。

以我个人的经验,很少能看完公众号上长篇的文章,基本翻几页就放弃了,或者先收藏着,然后从来也不会去打开收藏。所以还是分两次发布,上篇以股票领域为背景,介绍DDD的基本概念,下篇介绍如何在股票交易领域实践DDD。

等不及的朋友可以直接跳转到原文链接。

为什么采用事件风暴和领域驱动设计?

事件风暴和领域驱动设计的目标是创建一种技术无关的语言,达成对业务需求和流程的详细了解。让业务领域专家——这些最熟悉股票交易领域和业务角色的人——能够和团队的其他人分享领域知识。建模工作坊需要参与的干系人,可能包括技术专家、项目管理人员、用户体验专家、质量保证分析师,以及任何在项目运作中涉及的其他人;当然,最重要的人是业务领域专家。

同步系统依赖于请求/响应式语义;比如,我们调用一个方法或者Restful端点,并期待得到响应。 调用者收到响应前会一直等待。 如果响应延迟或失败了,会由于超时而导致资源无法获取。最起码,来自第三方系统任何的延迟都会导致服务明显的时延。

与之相反,我们将演示一个异步的,没有阻塞的系统开发。 因此,我们需要一种能够适应这种设计和开发风格的建模方法。

事件风暴和DDD允许我们以异步的方式建模,这很适合响应式,云原生系统分析和设计。

事件风暴介绍

事件风暴关注于召集项目所有的干系人,让大家对业务领域和身边的问题达成一致的理解,并且与技术无关。这使得解决方案建立在合适的业务上下文基础上,确保领域专家和技术专家在构建系统前达成一致的理解。事件风暴是一个高度协作的流程,经常能发现相当多的知识点。否则,它们只会留在个人和团队心中。

在事件风暴中,我们用橘黄色便签代表事件。起步很容易:干系人想一想,在桔色便签上写下感兴趣的业务事件,并把便签粘在某个固体表面上(比如墙上的空白纸,事后可以方便的卷起来)。在开始的10-10分钟时间里,或许有一些有趣的事件被识别出来。一旦我们有足够的事件,就需要创建流:事件流就是根据时间顺序从左到右排列的事件集合。

Why event storming and domain-driven design? The goal of event storming and domain-driven design (DDD) is to establish a technology-independent language and detailed understanding of the business needs and processes. This will allow the business domain experts — those most familiar with the stock trading domain and the role our business has in it — to communicate their domain knowledge with the rest of the team. Stakeholders involved in a modeling workshop may include technology experts, project management, user experience specialists, quality assurance analysts, and anyone else involved in the execution of this project; however, the most important people to include are the business domain experts.

Synchronous systems rely on request/response semantics; as in, we invoke a method or RESTful endpoint and expect a response. The caller blocks until receiving a response. If the response is delayed or fails, this can lead to resource starvation due to accumulating timeouts. At the very minimum, any delay when integrating with third-party systems can cause noticeable latency in our services.

In contrast, we will be demonstrating an asynchronous, non-blocking style of systems development throughout this series. For this reason, we need an approach to modeling that is complementary to this style of design and development.

Event storming and DDD allow us to model our system in an asynchronous way, which is suitable for reactive, cloud-native systems analysis and design.

Event storming introduction Event storming involves gathering all stakeholders of a project to align on a technology-neutral understanding of the business domain and the problem at hand. This grounds our solution in the appropriate business context, helping to ensure that the business domain experts and technology experts arrive at a common understanding before constructing a system. It is a highly collaborative process, and can often surface quite a bit of knowledge that would otherwise be siloed away within individuals and teams.

In event storming, we represent events with orange sticky notes. Getting started is easy: stakeholders simply begin to think of and write down interesting business events on orange stickies and affix them to a modeling surface (typically paper on a wall that can easily be rolled up when finished). Within 10-15 minutes of beginning an event storming session, we will likely already have a bunch of interesting events identified! Once we have enough events, we need to create flows: a flow of events is simply events in order from left to right, the order representing time.

An event storming workshop is a very dynamic experience. We may begin with a very simple flow of events. But shortly after a few events emerge on our workspace, a more detailed discussion is bound to emerge. Unlike more ‘formal’ modeling techniques, such as UML, communication and discussion are the most critical outcomes that emerge from this exercise. That’s not to say that we can’t keep the output of the workshop in the form of diagrams or other artifacts, but typically, we don’t want to turn valuable conversations into high-fidelity representations of those discussions right away. Event storming is all about the free flowing of communications.

Domain-driven design introduction Notice that we are starting to not only identify events, but also to surface a set of terms with specific business context. In the stock trader domain, we will use terms such as ‘stock,’ ‘quote,’ and ‘order.’ These will form the ubiquitous language of our business. We need to keep this consistent for the benefit of communication.

Domain-driven design gives us the blueprints to transform the output of an event storming session into models that are formal enough to use for architecting and building a real-world system.

We’ll now assume that readers have completed the prerequisites before continuing.

Getting started: The basics We’ll work through the modeling process to first establish a technology agnostic understanding of the stock trading business domain, using our business experts as the source of that knowledge. We’ll then translate those domain concepts directly into domain logic in our code, using the appropriate domain language. This will enable our technology experts and our business experts to stay closely aligned throughout the entire design and implementation of Reactive Stock Trader.

Through this early design process, we will use event storming to: Model the event and command flow of our stock trading system Assign commands and events into various subdomains that can be implemented by different teams Establish the interfaces between subdomains

Events We start the modeling process by identifying the important events in the system we’re modeling. An event is a factual statement of occurrence (for example, Stock Purchased). In other words, a set of events is a historical record of things that have happened in our system (or business). We will always express events in the past tense to reflect this.

In theory, we can model an entire business, no matter how complex, as a flow of events. In practice, however, it would be virtually impossible to gather tens of thousands of stakeholders from a large company in the same room in order to make any meaningful progress. For this reason, we must limit an event storming session to a targeted area of the business — not a targeted area of the technology — and further break down the process flows into domains and subdomains.

Typically, we kick off an event storming session by having all participants begin affixing events onto our workspace — any event that they find interesting enough to discuss. In our stock trading domain, a few interesting events are:

A client opened a new portfolio A client purchased some shares of a stock for their portfolio A client sold some shares of a stock from their portfolio A client closed their portfolio

As we begin to think of new events, we may notice that our event storming session is resulting in a pile of unordered events stuck to our workspace. As a more complete picture of the flow emerges, we will need to organize these events into a linear sequence. This can help to surface gaps in the business process.

For example, we might create a sequence ‘client opened a portfolio,’ ‘client purchased shares of stock.’ This might prompt us to ask, “What did they purchase the shares with?” Which we might respond to by adding a new domain event between those two events labeled ‘client adds cash to portfolio.’

We always start with events. Events are the natural foundation of a system, as they are the closest representation of the business processes involved, and entire discussions with subject matter experts can be formed around them. Other building blocks, such as commands, help us to elaborate on the processes and form a mental model of the asynchronous nature of the system.

Remember that event storming is an iterative process, so it may take many iterations between events and commands before we have modeled a process flow to some degree of accuracy, based on the business requirements.

Commands Commands are often the trigger for a sequence of one or more events, added as blue sticky notes to signal intent. While events are irrefutable statements about the past, commands express our intent for something to happen in the future.

However, commands can be refuted. For example, a command to ‘sell stock’ might be rejected if the client’s portfolio doesn’t hold the number of shares they wish to sell.

Commands are always present tense intentions, whereas events are always past tense facts.

Aggregates We will naturally begin to identify some aggregates, such as a Portfolio.

A Portfolio may contain some cash and also contain shares of various stocks. A Portfolio is an entity — that is, it has an intrinsic identity — so that even if your portfolio and my portfolio have the exact same amount of money and the exact same shares, they are still distinct from each other. For example, if I add some shares to my portfolio, it will still be the ‘same’ portfolio, even though the contents are different.

Entities, aggregates, and aggregate roots Before we continue, let’s cover some additional theory about the terms we’ve covered, namely entities, aggregates, and aggregate roots.

It’s often convenient to blur the distinction between an entity, an aggregate, and the aggregate’s root. This is similar to the way we might blur the distinction between an object graph and the root of the object graph. For example, a linked list can be thought of as a collection of linked nodes, or as a reference to the first node in the list. If we held a reference to the first node in that list, we wouldn’t hesitate to say that we held a reference to “the list.” If that list represented a queue of work to do, and we updated our work queue reference by following the reference between nodes, we would be thinking of the work queue as an entity, which changes state as we perform work on it. In this example, if we talk about the ‘work queue,’ do we mean the reference to the head of the list (entity), the head of the list (aggregate root), or an ordered collection of items in that list (aggregate)?

In practice, we often omit the distinction. At the level of detail we want to achieve during event storming, we’re typically concerned about state purely from a business context. If we keep that in mind, and ensure that our conversations remain accessible and engaging to non-technical stakeholders, we’ll likely be capturing the right level of detail. There will be time during more technical solutioning exercises to make the distinction with more rigor.

Modeling aggregates For aggregates, we use pale yellow sticky notes. Aggregates represent the state within our system. For example, a Portfolio is a natural aggregate. So is a Bank Account.

Aggregates are usually represented using persistent entities in Lagom. We will cover terminology in much more depth throughout the series. Aggregates are all about state, so we’ll need a way to change state. A command is directed to an aggregate and the only way that an aggregate can begin the process of changing state. This is an important distinction: commands do not force a state change. Commands kick off a series of operations that may or may not result in a state change. Aggregates can choose to change state, if the command is able to be applied, or ignore the command altogether.

As soon as an aggregate decides to change state, it emits an event that represents the change of state. For example, the ‘sell shares’ command would be applied to the entity that represents the client’s portfolio, and may lead to an event ‘shares sold’ and a change in the number of shares held by that portfolio. Applying the ‘shares sold’ event to the aggregate is the state change itself, and then that event is also emitted to subscribers.

Events may also be emitted if a state change is not possible. For example, an event called ‘sell order rejected’ may be emitted if a sale cannot be completed due to insufficient shares available.

Changes to the state of an entity happen only as a result of events. In order to recreate the state of the entity, we can start from the beginning of time and reapply all events that have ever happened in the aggregate boundary, which can be considered a transactional boundary. This is the core concept of event sourcing, which we will cover in depth throughout this series. During event storming, the events should be descriptive enough to paint a clear picture of any state changes that may or may not happen. The descriptive naming of events is the key to capture relevant business logic behind state changes, and also capture all possible outcomes of a command.

A general pattern that we’ll see is:

A command expresses intent for an entity to change state (for example, sell shares) An event expressing that the intended action has occurred is created (for example, shares sold) The entity’s state is updated based on the event The event is published for subscribers to consume

Actors and reactions Events happen because of a reason, such as user-initiated commands or machine-initiated commands.

The most common trigger of an event are user-initiated commands. Users are called actors in event storming parlance (not to be confused with Akka actors or the actor model) and attached to a command as a small yellow sticky. The main reason to use actor notation is that it makes planning and estimation much easier in later phases of modeling; any command with an actor associated with it will automatically be of interest to UI and UX teams, who can easily visualize the scope of their work.

Reactions (also known as policies) help to model system-initiated commands in response to events happening. For instance, we may want to initiate a command when something else happens. It’s this ‘when, then‘ notation that makes reactions very handy to use in modelling workshops. By convention, reactions are represented using lavender sticky notes. We can insert them between an event or a command, which makes it easy to model policies, with multiple commands being triggered from one event, or to attach the lavender sticky directly to a command, where a policy only has a single command associated with it.

The above flow is an example of an ecommerce process for adding products to a shopping cart. We leverage both actors and policies to paint a complete picture of our business requirements. We can see that a user is able to add an item to their shopping cart. We can also see that when the shopping cart is abandoned, we wish to send a follow-up email. 上图是电商中一个加入购物车的流程。 我们运用角色和策略,画了一个完整的业务需求图。可以看到,用户可以把商品加入购物车,当取消购物车时,会发出一封跟进邮件。

Event storming summary If you want to be an event storming legend, don’t forget your Event Storming Legend! Ours at RedElastic has been affixed to many walls and now requires much tape, but it does the trick. Event storming gives us a complete and simple (but expressive) modeling language to use during the initial phases of modeling, when collaboration is important, flexible, and fast-paced. We have introduced the bare minimum event storming vocabulary for you to get started using this technique in your own modeling sessions.

We highly recommend affixing both a legend and a sample flow in a highly visible place during your event storming workshops. This will give your teams a reference point as they collaborate.


Now that we have some basics of event storming covered, let’s apply what we’ve learned to the stock trader domain.

Modeling the stock trader domain Now that we have some basics of event storming covered, we’ll apply what we’ve learned to the stock trader domain. Rather than attempt to photograph or diagram the output of our event storming session in a high amount of graphical detail, we’ll instead work backwards and cover the structure of the system we’re going to build from the top down by documenting the output of event storming as pairs of commands and events. We arrived at all of these details through event storming, and then documented the details in the format you’ll see below.

Practice your event storming skills with your team by reverse-engineering the following bounded contexts! Hold a mock event storming workshop, and compare your output to our description below. This is a typical approach to event storming. Typically, models coming out of an event storming session are not turned into high-fidelity diagrams, but rather feed into design documentation and other planning artifacts. Remember, the value of event storming is communication, so there’s no way to substitute for actual participation. Attempting to capture the output of an event storming session in high-fidelity is an anti-pattern. Rather, we use event storming as a collaborative learning tool that makes our other processes, like domain-driven design, more effective and accurate.

Bounded contexts Our main unit of high-level structure is bounded contexts, which are categorizations of functionality that group related entities together.

In a real-world enterprise development scenario, a bounded context is often a team-level separation, with each bounded context being maintained by a team.

A good rule of thumb is that a bounded context should be comprehensible by an entire team, whereas an aggregate should be sized accordingly, so that it is easily understood by a single person. We’ll expand upon these concepts throughout this series.

For each bounded context, we will describe the commands and queries accepted, along with the events produced. Typically, bounded contexts are the last structures that are defined. However, in the case of this series, we’ll discuss them first to ground readers in context as they learn about the business domain.

Note: The following is a reasonable level of detail to capture after an event storming session to share with the team. We typically produce ‘design documents’ at this level of detail after a modeling session to share with stakeholders and communicate to a wider audience.

During event storming, we identified three bounded contexts within the stock trader domain:

Portfolio – business logic for customer portfolios Wire transfer – adapters for third-party wire transfers Broker – adapters to obtain stock quotes and execute trades Portfolio A Portfolio represents stock and cash holdings.

We will now describe the aggregate per in more detail. Recall that an aggregate represents state in our system, with commands acting on that state, and then events being emitted to communicate the details of state transitions to subscribers.

Portfolio aggregate The Portfolio is the most obvious aggregate. Here we’ll have stock holdings and cash funds to either withdraw or to use to buy additional shares.

We have identified the following command/event associations:

Command Event OpenPortfolio PortfolioOpened ClosePortfolio PortfolioClosed PlaceOrder OrderPlaced SharesDebited ProcessTrade SharesCredited FundsDebited FundsCredited TradeProcessed AcknowledgeOrderFailure OrderFailed ReceiveFunds FundsCredited SendFunds FundsDebited AcceptRefund RefundAccepted For each command, a Portfolio may produce one or more of the corresponding events in response.

The PlaceOrder command is not an atomic transaction resulting in the sale or purchase of shares for the portfolio. It produces the OrderPlaced (and possibly the SharesDebited) event, which is be handled elsewhere by the broker service.

In trading, there are a number of order types. For the sake of the stock trader application, we will demonstrate market orders, limit orders, and stop orders. The key difference between the types is that market orders will execute once there is a willing buyer or seller for the order, which means that the order may execute in near real-time. However, it’s possible that the order will never fulfill, in the event that the stock is illiquid. Limit and stop orders place additional conditions around the execution of the order, which gives us a good opportunity to showcase the dynamics of a reactive system. An order may stick around for days, weeks, or years before a limit is hit.

The portfolio is not responsible to actually fulfill orders directly, but rather to emit events that represent the orders that have been placed. The brokerage bounded context will be responsible for fulfilling orders, which we will cover shortly.

Summary This gives us the basic buildings blocks for our Portfolio bounded context. Next, we will cover wire transfers and how to move cash in and out of a portfolio.

Wire transfers Our next bounded context represents the cashflow through our system in the form of wire transfers. This will handle money in and out of portfolios. The wire transfer bounded context only contains a single aggregate, a wire transfer repository.

Wire transfer aggregate Our Portfolio subscribes to fund transfer events from the wire transfer aggregate and publishes its own acknowledgement events in response. This allows us to model wires to and from the portfolio. In the real world, transferring funds would typically be accomplished through a third-party wire transfer service. For this reason, we don’t want to couple wire transfers directly to our portfolio, but rather, we should consider a new aggregate boundary that is essentially an adapter in front of a wire transfer service. This allows us to interact with the third-party system using pub/sub semantics.

We have identified the following command/event pairs:

Command Event RequestFunds FundsRequested FundsSecured FundsRequestFailed SendFunds FundsSent FundsDelivered FundDeliveryFailed RefundSender SenderRefunded RefundFailed Summary If the transfer from our Wire Transfer aggregate to a third-party wire system fails for any reason, we can simply issue a compensating transaction to add the funds back to the portfolio. In a real-world architecture, we would likely event storm this with business stakeholders in greater detail to understand how to compensate from failure. But, for now, this is an appropriate level of detail to get started with a reference architecture.

Broker Clients hold a portfolio of stocks. They can purchase or sell stocks. This bounded context will represent the source of truth for stock holdings, and, in our case, interface with external systems to place trades themselves. We’re going to leverage a third-party brokerage service to perform quotes and trades.

In an enterprise context, this may be a system within your organization, but we’ll treat it as a third-party system (perhaps a completely separate bounded context outside of our control). Within our control (in othere words, our bounded context), we will create another adapter that gives us complete control of interactions.

Order aggregate This represents an order for a particular quantity of a particular stock symbol. We will attempt to fill this order and debit the portfolio balance. It is possible that purchase cost of the order may exceed the balance available in the account, in which case, the account is overdrawn. At some point in the future, we may want to limit the order based on available funds and perhaps holdings value. Each purchase incurs a commission payment; the commission amount is dependent on the loyalty level of the portfolio.

We have identified the following command/event pairs:

Command Event PlaceOrder OrderReceived CompleteOrder OrderFulfilled OrderFailed CancelOrder OrderCanceled The order can represent a market, limit, or stop, and be either a buy or a sell request.

Quote service The quote service isn’t necessarily an aggregate, but it’s worth mentioning here, as we’ll need to integrate with it on the server side in order to compute portfolio balance.

The reason that a quote is not an aggregate is because it isn’t stateful. A quote is effectively a wrapper around a third-party web service.

Trade service The trade service simulates the custodian service that we would integrate with, if this were a real-world stock trading system.

Reactive Stock Trader won’t hold stocks directly, but rather act as an interface to a custodian system. A custodian system may be an internal ‘book of record’ system in a large bank, or a third-party custodian. The trade service will simulate the actual fulfilment of orders or the cancellation of orders due to user input or failure.

Summary & next steps We hope that this unit has demonstrated a new way of thinking about systems architecture. Why might we benefit from learning this new approach to building systems, and why choose a reactive approach?

Suppose we have an existing stock trading system. We’ve likely learned many things about the business of stock trading and what it takes to run a stock trading platform. Now assume our platform has achieved so much success that we’re starting to run into two specific technical challenges: elasticity and resilience.

As we described at the beginning of this unit, the aim of reactive systems development is to create completely responsive systems. In order to do this, they need to be elastic and resilient. We achieve elasticity and resilience through asynchronous messaging in the form of commands and events. As we work through this series, the power of these simple principles will become more clear.

In this unit, we have covered the building blocks of designing such as a system, and as we move through the rest of this series, we will showcase how to build and deploy robust reactive systems that are responsive at runtime and responsive to the needs of your business.

Read More

Event storming(translate)

https://developer.ibm.com/technologies/java/tutorials/reactive-in-practice-1/#

DDD事件风暴(上)——原理篇

前言

范钢老师在devops社区的系列分享第一篇-《快速交付》之设计篇,以电商中的购物环节为例,利用领域驱动设计方法来建模,介绍了事件风暴,聚合,聚合根,命令等一系列概念。作为DDD的入门者,这些概念还是比较模糊的。在IBM Developer找了一篇文章,详细介绍了DDD的基本概念和实践,翻译出来与大家分享。

以我个人的经验,很少能看完公众号上长篇的文章,基本翻几页就放弃了,或者先收藏着,然后从来也不会去打开收藏。所以还是分两次发布,上篇以股票领域为背景,介绍DDD的基本概念,下篇介绍如何在股票交易领域实践DDD。

等不及的朋友可以直接跳转到原文链接。

为什么采用事件风暴和领域驱动设计?

事件风暴和领域驱动设计的目标是创建一种技术无关的语言,达成对业务需求和流程的详细了解。让业务领域专家——这些最熟悉股票交易领域和业务角色的人——能够和团队的其他人分享领域知识。建模工作坊需要参与的干系人,可能包括技术专家、项目管理人员、用户体验专家、质量保证分析师,以及任何在项目运作中涉及的人;当然,业务领域专家最重要的。

同步系统依赖于请求/响应式语义;比如,我们调用一个方法或者Restful端点,并期待得到响应。 调用者收到响应前会一直等待。 如果响应延迟或失败了,会由于超时无法获取资源。来自第三方集成系统任何的延迟,最起码会导致服务明显的时延。

与之相反,我们将演示一个异步的,没有阻塞的系统开发。为此,需要一套能够适应这种设计和开发风格的建模方法。

事件风暴和DDD允许我们以异步的方式建模,非常适合响应式系统和云原生系统的分析和设计。

事件风暴介绍

事件风暴召集项目所有的干系人,让大家对业务领域和身边的问题达成一致的理解,这种理解无关乎技术。解决方案建立在合适的业务上下文基础上,确保领域专家和技术专家在构建系统前达成一致的理解。

事件风暴是一个高度协作的流程,经常能发现相当多的知识点。如果不采用这种方法,它们只会藏个人和团队心中。

在事件风暴中,我们用橘黄色便签代表事件。起步很容易:干系人想一想,在桔色便签上写下感兴趣的业务事件,把便签粘在某个固体表面上(比如墙上的空白纸,事后可以方便的卷起来)。在开始的10-10分钟时间里,或许有一些有趣的事件被识别出来。一旦我们有足够的事件,就需要创建流:事件流就是根据时间顺序从左到右排列的事件集合。

事件风暴工作坊是一个非常动态的体验, 我们可能从一个非常简单的事件流开始。随着一些事件被发现,必然会伴随着更细致的讨论。和UML等较正式的建模技术不同,沟通和讨论是这个练习最关键的输出。这并不是说,工作坊不能输出图表或其他的构件,主要是不希望这么快把有价值的对话变成固定的表示。事件风暴本身就是自由的沟通讨论。

领域驱动设计介绍

请注意,我们不仅仅识别事件,也开始发现特定业务上下文中的一些术语。在股票交易领域,我们将使用术语“股票”, “报价”,订单”,它们将变成业务通用语言。保持一致性有利于交流。

领域驱动设计给了我们一个模板,可以把事件风暴的输出转变成模型,足够正式,可以用于架构和构建真实世界的系统

在继续之前,我们假设读者已经理解了这些预备知识。

准备开始:基础

我们会走一遍建模流程,了解股票交易业务领域,把业务专家作为知识源。然后,使用合适的领域语言,把领域概念转变成代码中的领域逻辑。这会让技术专家和业务专家在整个设计和实现中始终保持一致的理解。

经过这个初步的设计流程,我们利用事件风暴做到:

  1. 对股票交易系统的事件和命令流建模。
  2. 把命令和事件归到不同的子域(subdomain),可以给不同的团队去实现。
  3. 在子域之间创建接口

事件

先从识别重要的事件开始。 事件是对已发生事实的陈述(比如,股票已购买)。换句话说,一个事件集是指系统中已经发生的一些历史记录。事件一般用过去时态来表达。

理论上, 无论有多复杂,我们都可以对整个业务建模,形成一个事件流。 不过,实际上,不太可能把一个大公司中所有的干系人都请到房间,期待取得任何有意义的进展。所以,我们得把事件风暴限制在一个在特定的业务领域——不是技术领域——然后进一步把流程分解到各个领域和子领域中。

一般来说,事件风暴会议启动后,参与者都开始往墙上贴事件——任何有趣的,值得讨论的事件。在股票交易领域,有趣的事件包括:

  • 客户打开了新的投资组合。
  • 客户购买了投资组合中的一些股份。
  • 客户卖出了投资组合中的一些股份。
  • 客户关闭了投资组合。

当我们继续考虑新的事件时,可能会注意到,事件风暴会议产生了一堆无序的事件。当有比较完整的事件流显现时,我们需要把这些事件排成一个线性的顺序。这有助于发现业务流程中的差距。

比如, 我们创建一个序列“客户打开了一个投资组合”,“客户购买了一些股份”。它会提醒我们思考,“客户用什么买的?” ,由此,我们会在两个事件之间增加一个新的领域事件“客户往投资组合中增加了现金”。 image

我们通常从事件开始。事件是一个系统天然的基础,因为它们是业务流程最贴切的表示法,能围绕它们和主题专家展开讨论。另外的构建块,比如命令,帮助我们详细阐述流程,构造出异步系统的内在模式。

事件风暴是一个迭代式的流程,可能需要多个迭代来讨论事件和命令,才能形成一个基于业务需求的,比较准确的流。

命令

命令通常是一个或多个事件序列的触发器,用蓝色便签来记录。事件代表着过去不可改变的事实,而命令用来表达让事情在未来发生的意图。

命令可以被驳回。比如,由于客户投资组合中没有足够的股份,导致“卖出股票”这个命令被驳回,

命令通常用现在时态来表示,而事件总是过去时态。 image

聚合

我们可以轻易的识别一些聚合,比如一个投资组合。

一个投资组合可能包括一些现金和各种类型股票。 一个投资组合也是一个实体——也就是,它具备固有的识别特性——因此,即使你的投资组合和我的组合有同样数目的钱和股票,它们彼此仍是不同的。我往组合里增加一些股份,它还是原来那个组合,即使里面的内容不一样了。

实体,聚合和聚合根

继续之前,我们对实体,聚合和聚合根这些术语再做些补充。

实体,聚合和聚合根之间的区别很容易搞混。 就像我们总是搞不清java中的对象图和对象图根对象的关系一样。

举个例子,一个链接列表可以看成是彼此连接的节点集合,也可看成是指向列表中首节点的引用。如果我们取得了首节点的引用,我们会毫不犹豫的说我们获取了整个“列表”的引用。

如果这个列表表示工作项队列,通过节点之间的引用可以更新工作队列。我们会把工作队列当成一个实体, 随着工作的进行,它的状态会改变。

在这个例子中,当我们谈及“工作队列”时,我们是指列表头节点的引用(实体),列表的头节点(聚合根),还是列表中元素的有序集合(聚合)呢?

在实践中,我们经常忽略这些区别。在事件风暴会议中,保持一定水平的细节程度是必要的,我们主要关心的是基于业务上下文的描述。明白了这一点,只要确保对话是彼此可理解的,同时有非技术的干系人参与,这个细节程度就是合适的。在后续的技术方案练习中,会有更多的时间来弄清它们之间的区别。

聚合建模

我们用淡黄色便签表示聚合。聚合代表系统中有状态的实体。比如,一个投资组合是聚合,一个银行账户也是。

聚合都是与状态相关的,那就还得有改变状态的方法。命令指向聚合,这是改变聚合状态的唯一办法。有一点要特别注意,命令不会强制去改变状态。当聚合接收到命令时,可以选择改变状态,或者完全忽略它。

一旦聚合决定改变状态,会发出一个表示状态变更的事件。比如, “出售股份”命令作用到“投资组合”,会产生一个事件“股份已售出”,同时组合中的股份数会减少。投资组合的状态变了,而且“股份已售出”这个事件也会发布给订阅者。

如果状态无法变更,也可以发出事件。比如,由于股份不足无法完成交易,会发出一个“交易已拒绝”的事件。

改变实体状态只能通过事件。要重建实体的状态,我们可以从头开始,把聚合范围内(也可认为是事务边界)曾经发生过的事件重新触发一遍。 这是事件溯源的核心概念,在后面的系列中会深入探讨。

在事件风暴中,要描述清楚所有的状态变更,事件本身要有足够的“描述性”。事件的描述命名是捕获状态变更背后相关业务逻辑的关键,也是捕获命令所有可能输出的关键。

至此,我们可以看出一个通用的模式:

  1. 一个命令表达想改变实体状态的意愿(比如,卖出股份)
  2. 一个事件表示预期的动作已经完成(比如,股份已卖出)
  3. 实体状态基于事件来更新
  4. 事件会广播给各个订阅者去消费

image

角色(Actors)和响应(Reactions)

事件可以由用户执行操作触发,也可由系统内部命令触发。

事件通常是由用户操作触发的。用户在事件风暴中称为角色(actor)(不要和Akka框架中actors混淆),用小的黄色便签,粘在命令上。 之所以采用角色标记法,是为了在后面的建模过程中方便计划和估算;UI和UX团队会自动关注与角色相关的所有命令,能够轻易的界定工作范围。

响应(也被称为策略-Policies)用来给触发事件的系统内部命令建模。比如,当符合某一条件时,就启动一个命令。这时,采用“当…时,就…..”标注法来建模就很方便。按照惯例,响应用淡紫色的便签表示。当事件对应多个命令时,可以在命令和事件之间插入策略。或者直接把策略附在命令上,这时,一个策略只对应一个命令。

image 上图是电商中一个购物车的流图。我们运用角色和策略,画了一个完整的业务需求图。可以看到,用户可以把商品加入购物车,当取消购物车时,会发出一封跟进邮件。

事件风暴总结

在建模的初始阶段,协作很重要,同时也是灵活和快节奏的。事件风暴给我们提供了一种完整,简单而又不乏表达力的建模语言。以上介绍的关于事件风暴最小集词汇,让你能在建模会议中开始运用这项技术。

在事件风暴工作坊中,我们强烈建议在显眼的位置贴上图例和样例流图,供团队参考。 image

Read More

Spotify Mission

https://mission-statement.com/spotify/

Introduction Spotify’s mission and vision statements have given the company a global image with the emphasis they lay on operational effectiveness. As an online music streaming network, Spotify has recognized how to strategize and command a large following through its mission and vision statement. This is an element that the founders of this company, Martin Lorentzon, and Daniel Ek, stimulated from its early days in 2006, and truly, it has born the intended fruits having made the company grow into one of the biggest with over 217 million users.

All this growth has been due to these two corporate statements together with the core values of the company. A corporate vision statement is all about what the business target the management of the company wants to achieve, while a corporate mission statement basically defines the operations that a business embarks on to meet its objectives. Spotify’s vision statement emphasizes how influential the company is in matters related to digital content exchanges and how it enriches this.

On the other hand, the mission statement of this company emphasizes the direct benefits that both of its users get from the company. It also reveals that though they have different needs, the magnitude and the quality of experience they get is practically equal and well-balanced. These two corporate statements greatly depend on values such as sincerity, collaboration, and innovativeness among others that the company incorporates to act as a guide to the overall operations in the company.

The company judiciously implements is corporate statements and stays within the expectations of the core values, and this has gone a long way in giving it a strong foundation and consistency in what it does.

Spotify Mission Statement Spotify’s mission statement is “to unlock the potential of human creativity by giving a million creative artists the opportunity to live off their art and billions of fans the opportunity to enjoy and be inspired by these creators.” The mission statement sheds more light on the goals of the company and how it wants these goals to become a reality. It has the following key features:

Improving lives. Spotify satisfies this feature by being an interactive and up-to-date platform that its users can depend on. The company acknowledges how critical digital space is for its target audience in creating sustainable livelihoods for themselves. Within Spotify’s platform, for instance, artists have a better chance of reaching out to a wider fan base. The targeting criteria used by the company ensures that the digital content created by an artist reaches the most appropriate audience, making it profitable for these individuals. In fact, this echoes what the mission statement means by enabling the artists ‘to live off their art.’ Encourages the sharing of digital content. The primary undertaking of Spotify is to provide medium and boost dissemination of content to the users. It actually links the artists to the consumers of their work, something that tremendously encourages sharing. At the basic level, this is what Spotify does, however, it also incorporates commercial elements that ensure the content producers benefit from their work as shown in the first component of the mission statement. Global presence. To ensure that Spotify reaches out to as many users as possible, the management adopted a strategic approach that captures the needs of everyone at the global level. The approach means that there is no limitation to anyone who can use Spotify including both target audiences – artists and fans. As stated by Ek, the company looks to connect everyone, irrespective of cultural, genre and other boundaries. That explains why the company boasts of having a coverage of millions of artists and billions of fans, which can only be possible for a company whose reach goes beyond regional to a global scale. Vision Statement Spotify’s vision statement is “We envision a cultural platform where professional creators can break free of their medium’s constraints and where everyone can enjoy an immersive artistic experience that enables us to empathize with each other and to feel part of a greater whole.” The statement brings to light how strategic Spotify is to an extent of ensuring it offers win-win services for both the artists and the fans such that both not only feel appreciated but also part of the bigger picture or vision of the company. The statement incorporates the following points:

SEE ALSO apple mission statement vision statement Apple Nike google mission statement vision statement Google amazon mission statement vision statement Amazon starbucks mission statement vision statement Starbucks Walmart Stimulate empathy and harmony. Spotify does not see itself simply as a service provider. The company takes a much bigger role, that exceeds satisfying the on-demand music needs in the industry, to having a more socially rooted role in society. Considering that the company mentions the culturalism within its platform, it is clear the company seeks to weave a sense of linkage creation between people in whatever it does. In this way, it brings global communities together. Break medium constraints. Within the music industry, the model used by Spotify identifies and addresses a critical element that had stalled the progress of the artists for ages – medium barriers. In response to this, the company came up with an open yet well-regulated option that provides the artists with an opportunity to test their creativity with little worries about the market for the content they produce. This is because that element is adequately taken care of by Spotify. Core Values Spotify’s core values include “passionate, innovative, sincere, collaborative, and playful.” These values are what the corporation considers as the guiding principles that keep everything within the expectations of the management. They also ensure the success of the mission and vision statement by ensuring everyone stays realigned to the goals and objectives of the company.

Spotify understands that people do best when they engage in what they love most. In fact, this is exactly what fuels creativity that leads to new designs and approaches as expected in the presence of the first and second values. The corporation that characterizes Spotify adds to its success, and this is also a reflection of the company’s emphasis on sincerity and respect for each other. Just as stated in the old adage that ‘all work and no play makes Jack a dull boy,’ Spotify averts such boredom and laxity by promoting a culture of appropriate playfulness in its settings, and while interacting with others.

References Bhoot, G. (2017). Music Industry Sales: How streaming services such as Spotify, Apple Music, and TIDAL affect album sales. Chaffey, D., & Ellis-Chadwick, F. (2019). Digital marketing. Pearson UK. Collins, J. C., & Porras, J. I. (1996). Building your company’s vision. Harvard business review, 74(5), 65. David, F. R., & David, F. R. (2003). It’s time to redraft your mission statement. Journal of Business Strategy, 24(1), 11-14. Dawson, A., Hirt, M., & Scanlan, J. (2016). The economic essentials of digital strategy. McKinsey Quarterly, 3, 45. Doyle, P. (1992). What are the excellent companies?. Journal of Marketing Management, 8(2), 101-116. Salameh, A., & Bass, J. (2018, November). Influential Factors of Aligning Spotify Squads in Mission-Critical and Offshore Projects–A Longitudinal Embedded Case Study. In International Conference on Product-Focused Software Process Improvement (pp. 199-215). Springer, Cham. Shankar, V., Kleijnen, M., Ramanathan, S., Rizley, R., Holland, S., & Morrissey, S. (2016). Mobile shopper marketing: Key issues, current insights, and future research avenues. Journal of Interactive Marketing, 34, 37-48. Spotify – About. Voigt, K. I., Buliga, O., & Michl, K. (2017). Passion for Music: The Case of Spotify. In Business Model Pioneers (pp. 143-155). Springer, Cham. Vonderau, P. (2019). The Spotify effect: digital distribution and financial growth. Television & New Media, 20(1), 3-19. Wlömert, N., & Papies, D. (2016). On-demand streaming services and music industry revenues—Insights from Spotify’s market entry. International Journal of Research in Marketing, 33(2), 314-327.

Read More

Spotify vision

https://bstrategyhub.com/spotify-vision-mission-core-values-a-complete-analysis/

Company: Spotify CEO: Daniel Ek Founders: Daniel Ek and Martin Lorentzon Headquarter: Stockholm, Sweden Number of Employees (Dec 2018): 3651 Type: Public Ticker Symbol: SPOT Annual Revenue (Dec 2018): $ 5.26 Billion Profit |Net income (Dec 2018): (- $ 78 Million)

Products & Services: Online music Competitors: Apple iTunes Store | Amazon Music | Google Play | Pandora

Did You Know – As of June 2019, Spotify has 232 million monthly active users

Introduction Spotify’s vision, mission, and core values have established the global image of the organization along with an emphasis towards the effectiveness of their operation. Thus, through its vision and statements, Spotify has obtained and identified a path to command and strategize a large following as a network of online music streaming.

From its early days in 2006, both Daniel Ek and Martin Lorentzon, who are the founders of the company, incorporated this element in the operational activities of the business. This allowed the company to grow rapidly with 232 million monthly active users.

Spotify’s Vision Statement The vision of Spotify is :

“We envision a cultural platform where professional creators can break free of their medium’s constraints and where everyone can enjoy an immersive artistic experience that enables us to empathize with each other and to feel part of a greater whole.”

In this regard, the vision of Spotify is based on its objective to ensure that its services result in a win-win situation for the fans as well as the artists. This allows them to feel a sense of belonging to the vision and bigger picture of the company, along with the feeling of being appreciated.

The vision statement of Spotify is based upon the following points:

Stimulating Harmony and Empathy: Spotify emphases on acquiring a more significant role rather than merely identifying itself as a service provider. The focus of the company seeks to perform a socially rooted role in society, instead of only fulfilling the needs and requirements of the industry by providing on-demand music. The idea of Spotify lies in the fact of weaving and developing a sense of linkage and connection between people in everything that it does, which is highlighted from the incorporation of culturalism within the platform of the company.

Breaking from Medium Restrictions and Constraints: The application of medium barriers have significantly hindered the progress of the artists over the long term. However, the model utilized by Spotify within the music industry addresses and identifies this critical element. To resolve this issue and offer better and improved opportunities for growth, Spotify identified and adopted a well-regulated, yet an open option that allowed the artists to test their creativity. As Spotify monitored this element, therefore, it was adequately taken care of without placing any pressure on the artists.

Spotify’s Mission Statement The mission statement of Spotify is based upon the idea, which is as follows:

“Our mission is to unlock the potential of human creativity – by giving a million creative artists the opportunity to live off their art and billions of fans the opportunity to enjoy and be inspired by it.”

Spotify’s mission statement focuses on the transformation of these goals into reality and directed towards the achievement of the goals of the company from a broader perspective. In this regard, these are the key features of their mission statement:

Improving Lives of the General Public: To ensure that the feature is satisfied, Spotify ensures that its platform is up-to-date and interactive. In this regard, the need to create sustainable livelihoods and providing a critical digital space is for its target audience is acknowledged by the company significantly. Artists have a better chance to access and reach out to their broader fan base more efficiently by utilizing the respective platform of Spotify.

Furthermore, to make sure that the digital content produced by the artists reaches the appropriate audience through its criteria of targeting, hence making it profitable for individuals. As a result, the idea of enabling the artist “to live off their art” is echoed in the mission statement.

Global Presence: The management of Spotify implemented a strategic approach that reaches out to as many users as possible so that the needs of the users can be satisfied at a global level. The principle idea of this approach is to ensure that their limitation for anyone, regardless of being a fan or an artist upon using the app. Regardless of genre, culture, or any other boundary, the company focuses upon ensuring connectivity with everyone. This can be identified from the fact that Spotify is proud of having coverage for accessing billions of fans and millions of artists, which allows it to reach its users on a global level.

Spotify’s Core Values The core values of Spotify are:

Innovation Passion Collaboration Transparency Fairness As a result, everything is under check and in place in accordance with the expectations of management as these guiding principles are taken into consideration. Thus, Spotify’s management seeks to attain alignment with the objectives and goals of the company for the overall success of the vision and mission statement.

Spotify recognizes the fact that people do best upon their engagement with what they admire the most.

As a result, new approaches and designs are developed from the emergence of creativity according to the core values of the organization.

In addition, the emphasis on respect and sincerity is a significant reflection on the success of Spotify as the company promotes a culture of appropriate playfulness in its settings to avert boredom, while simultaneously interactive with everyone.

References & more information

https://newsroom.spotify.com/company-info/

https://www.businessinsider.com/spotify-ceo-daniel-ek-letter-to-investors-2018-2

Read More

Code review in linkedin

https://thenewstack.io/linkedin-code-review/

LinkedIn recently passed the milestone of having conducted one million code reviews. The head of the social networking service’s tooling shared a few learned lessons along the way.

Reading and reviewing code is something every engineer does on a daily basis. A formal code review process, however, is a bit different — it requires every code change to be officially reviewed by another team member before the code goes to production. At LinkedIn, code reviews have been a mandatory part of our development process since 2011. Our goal in requiring code reviews was to scale our rapidly-growing engineering team as smoothly as possible. Good code reviews with meaningful, useful comments can really help with leveling up an entire engineering organization. At LinkedIn, these reviews have become an essential part of quality assurance and knowledge sharing. Embracing code reviews has changed our whole engineering culture for the better in several key ways.

One of the biggest benefits of implementing company-wide code reviews has been increased standardization in our development workflow. Every team at LinkedIn uses the same tools and process for doing code reviews, which means that anyone can help with reviewing or contributing code for another team’s project. This eliminates problems like “I could fix the bug in their code, but how would I build that code and submit the fix?” This, in turn, helps increase collaboration across different teams in the engineering organization.

By making code reviews a mandatory process, we’ve also helped foster a healthy feedback culture at the company: engineers are open to giving and receiving feedback in all areas of work, not just in coding because it’s become a routine component of the job. Rather than viewing code reviews as critical or negative, our engineers use both giving and receiving code reviews as opportunities to grow professionally. In fact, high-quality code reviews are an important part of LinkedIn’s promotion process because they provide objective evidence of engineering skill.

Over the years, we’ve honed several best practices and tips for how to give truly great reviews. Below are some guidelines, in the form of questions, that we suggest asking to help make sure the reviewer and reviewee are getting the most value possible out of a code review.

Do I Understand the “Why”?

To facilitate the best review possible and help your team scale, every code change submission should include a design overview that briefly explains the motivation behind the change. It is really hard to offer a high-quality code review when the rationale needs to be inferred from the code change itself. It is fair to ask and expect the submitter to explain their motivation before attempting the code review. This also encourages the submitter to have an explanation in their commit message, increasing the quality of code documentation.

Am I Giving Positive Feedback?

In an organization full of smart people, clean code and neat test coverage can be taken for granted. As a result, code review feedback tends to focus only on problems and issues found in the code. This is very unfortunate because most people need positive feedback to feel engaged and motivated — and engineers are no exception. When a reviewer sees good stuff in the code, they should call it out and give positive feedback. This helps improve team dynamics, and often such positive feedback is contagious. As with all code review comments (more on this below), any positive feedback should be specific, explaining why that particular code is well-written.

Is My Code Review Comment Explained Well?

Whether the feedback is positive or negative, any code review comment should be self-explanatory. What might seem obvious to the reviewer can be unclear to an engineer who receives poorly-explained code review comments. When in doubt, it is better to over-explain than to provide terse feedback that yields more questions and the need for more back-and-forth communication. Explanations can be as simple as “reduces duplication,” “improves coverage,” or “makes code easier to test.” In addition to making reviewers’ comments clearer, these types of explanations also help reinforce the design principles that the team aspires to meet.

Do I Appreciate the Submitter’s Effort?

Hard work always needs to be appreciated, regardless of the outcome — this fosters strong, highly motivated teams. Some code changes are not of the highest quality and will need to be reworked. In those situations, it’s important to still acknowledge the effort that the author put into the changes, even if their code needs reworking. The best way to show appreciation is to put effort into your code review by giving high-quality feedback with decent explanations, acknowledging the good ideas (there are always good things in every code submission!), and using “thank you.”

Would This Review Comment Be Useful to Me?

Asking this question is an easy and powerful way to validate if the code review comment is necessary. At the end of the day, engineers should view code reviews as helpful development tools, and not sources of unimportant busywork. If you don’t think a particular review comment would be useful to you, then remove it. A classic example of unhelpful code review comments are ones related to code formatting. Code style and formatting should be validated by automated tools, not engineers.

Is the “Testing Done” Section Thorough Enough?

At LinkedIn, every code change submission has a mandatory “testing done” section that needs to be filled out. In the open source world, using GitHub as an example, engineers can submit “testing done” information in the pull request description. What should be in “testing done” depends on the gravity of the changes and the current level of test coverage. If the change contains new or altered conditional complexity, it is fair to expect it to be covered in unit tests. Some changes may require running manual testing if the integration test coverage is inadequate. In those cases, “testing done” should include information about the test scenarios and the outputs. When changes alter the output of the program, it is very useful to include the new output in the “testing done” section.

Am I Too Pedantic in My Review?

Some code reviews have so many comments that important issues — ones that really need to be fixed — are lost among less important suggestions. Reviews that are too heavy on details for a given team can slow down the review cycle and cause friction for both the reviewers and reviewee. Having clear review expectations, example reviews, and a positive, inviting review culture are great ways to avoid lengthy, exhausting review cycles.

In summary, having a formal code review process helps improve code quality, team learning, and knowledge sharing. The quality of work increases when every engineer on the team realizes two important things: someone else will read my code, so it better be good, and I’ll have to address any review comments I receive, so I should try to make my code good the first time around to save myself effort later on. When code reviews become an everyday habit, the team practices giving and receiving feedback on a daily basis. This is key for growth and improvement.

At LinkedIn, we’ve learned a lot from the past one million code reviews, and we aspire to learn even more from the next million. The more effort that’s put into code reviews, the better a team gets at giving great code reviews, the higher the quality of code that is checked in, and the higher the quality of the product that’s built. High-quality code reviews are contagious!

The author thanks James Miller, Oscar Bonilla, Joshua Olson, Andrew Macleod, Scott Meyer, and Deep Majumder for insightful feedback on this article.


https://thenewstack.io/linkedin-code-review/

在LinkedIn,代码评审最近达成了100万行的里程碑。这家社交网络工具的领头羊,分享了一路走来获得的收获。

代码阅读和检视是工程师每天都要做的事。正式的代码评审流程,有一点点不同——每一次代码更新,在部署到正式环境之前,都需要经过其他团队成员正式的评审。自2011年以来,代码评审在LinkedIn已经变成了开发流程中必须的一部分。它的目标是尽可能平滑的衡量快速成长的工程队伍。

有意义的代码评审反馈,对提升整个工程组织的水平很有帮助。在LinkedIn,评审已经成了质量保证和知识分享中的核心部分。拥抱代码评审让整个工程文化在某些关键方面变得更好。

在公司层面实施代码评审,一个最大好处是提升了开发流程的标准。每个团队用的是同一套工具和流程,意味着每个人都能帮助别的项目团队评审或贡献代码。能消除诸如“我可以修复那段代码中的bug,但我怎么构建并提交修复呢?”之类的问题。 并且有助于增进组织中不同团队之间的协作。

把代码评审作为一个必需的流程,有助于促成健康的反馈文化:工程人员愿意提出或接收工作中各方面的反馈,不仅仅是代码,因为这已经变成了日常工作的一部分。

工程师并没有把代码评审看成是批评或负面的,而是把它作为一个提升专业的机会。事实是,高质量的代码评审是linkedIn晋升流程的一个重要部分,因为它提供了衡量工程技术的客观证据。

多年来,对于如何真正做好评审,我们打磨了一些最佳实践和技巧。下面给出一些指导方针,以问题的形式来展现。在代码评审中问一问自己,可以帮助双方获得最大的价值。

我理解“为什么要这么做”吗?

为了促进最大可能的评审,并帮助团队衡量,每次代码变更的提交都需要包含整体设计,用来简单解释变更背后的动机。如果需要从代码本身去推断实现原理,就很难做到高质量的代码评审。

在评审之前,期望提交人解释下代码变更的动机,这样的要求也是很合理的。同时也是鼓励提交者在提交时写好注释, 提高代码文档的质量。

我提供了积极的反馈吗?

在一个都是聪明人的组织里,干净的代码和整洁的测试覆盖率被认为是理所当然的。因此,代码评审仅会关注代码中的问题。

非常不幸的是,大部分人需要获取积极的反馈,才能让自己有参与感或者被激励——工程人员也不例外。 当评审者看到代码中好的方面时,应该说出来,给予积极的反馈。这有利于改善团队动力,经常性的正面反馈会有感染力。

正如代码评审的评语(后面会详细介绍)一样,任何积极的反馈内容需要非常明确,指出为什么那段代码写的特别好。

我的评审反馈解释清楚了吗?

无论反馈是积极的还是负面的,任何评语应该是自解释的。不怎么完善的评语评审者自己能看懂,但对于代码提交者来说,却不会那么清楚。当有疑问时,解释充分点会比较好,太简洁反而会掩盖更多问题,并需要来回多次的沟通。

当然,解释也可以很简单,比如使用“减少重复”,“完善覆盖率”,或者“让代码更容易测试”这样的重构术语。不但让评论更清晰,也会帮助团队进一步巩固设计原则,

我感激提交者的努力吗?

无论结果怎样,努力工作总是值得赞赏——这会增强团队的积极性。有些代码变更的质量不是很高,需要返工。即使这样,仍然要承认提交者的努力,这点很重要。

展示感激的最好办法是在代码评审中给出高质量的反馈,得体的解释,承认做的好的部分(任何提交的代码中总有好的一面),以及说声“谢谢你”。

代码评审的评语对我有用吗?

在验证评审评语是否必要时,这样问自己一下,简单又有效。

最终,工程师会把代码评审看成利于开发的工具,而不是无关紧要的额外工作。如果你认为某条评语没用,就删掉。无用评语很典型的例子就是关于代码格式的。代码风格和格式应该由自动化工具来验证,不是工程人员。

“测试完成” 区足够充分吗?

在LinkedIn,每次代码变更提交都必须填写“测试完成”区。在开源领域,比如GitHub,工程师能够在拉取请求(pull request)的描述中填写“测试完成”信息。

测试完成区里填写的信息取决于变更的比重以及当前的测试覆盖水平。假如变更包含新的或者更改的条件复杂度,应当有相对应的单元测试。如果集成测试覆盖率并不充分,则需要运行手工测试。

以上的情况下,”测试完成”区应该包括测试场景以及输出结果。当变更改变了程序的输出时,把新的输出结果放在“测试完成”区是非常有用的。

在评审中我是否太学究派了?

有些代码评审评语太多,使得真正重要的问题(确实需要解决的)被淹没在不重要的建议中。评审太关注于细节,会拖慢团队的评审循环,让评审双方人员产生摩擦。为避免冗长,令人疲惫的评审循环,需要有清晰的评审期望,评审案例,以及积极的,吸引人的评审文化。

总之,正式的代码评审流程帮助团队改善代码质量,团队学习和知识分享。当团队的每个成员意识到以下2个要点时,工作质量将得到提升:

别人会读我的代码,因此最好写的好点。还有,我需要处理收到的评审反馈,为节省以后修改的时间,我应该第一时间就把代码写好。

当代码评审变成了每个人的习惯, 团队每天都在实践反馈的输出输入。这是成长和改善的关键。

在LinkedIn,我们从过去100万行的代码评审中学到了很多,我们也期待从下一个100万中学到更多。

代码评审中投入的精力越多,团队在评审中就会给出更好的反馈,提交的代码质量也更高,从而构建的产品质量也更好。高质量的代码评审具有传染性。

The author thanks James Miller, Oscar Bonilla, Joshua Olson, Andrew Macleod, Scott Meyer, and Deep Majumder for insightful feedback on this article.

Read More