软件 规则引擎

想象一下这种情况 (Imagine this scenario)

You’re a busy engineer working in a company with too much to build and too few resources to do it. Departments constantly ask for changes only an engineer can make. Marketing continuously asks for email on-boarding changes. Operations wants more and more batch tooling. Sales wants to test new pricing structures every other week. You and your team are overwhelmed with requests.

您是一个忙碌的工程师,在一家公司里工作,要建立的东西太多,而要做的东西却很少。 各个部门不断要求只有工程师才能进行的更改。 市场营销不断要求更改电子邮件注册。 运营需要越来越多的批处理工具。 销售人员希望每两周测试一次新的定价结构。 您和您的团队不知所措。

What are your options?

您有什么选择?

Stop progress on planned work to make these requested changes? A constant stream of interruptions is terrible way to get any real work done, and who knows if these asks are even worth interrupting the real work for.

停止计划中的工作以进行所需的更改吗? 持续不断的打扰是完成任何实际工作的可怕方式,谁知道这些要求是否值得中断真正的工作。

Ignore it? You’ll make progress on your planned work, but you’ll also have a bunch of external stakeholders now suddenly very angry at your department. Besides, isn’t technology supposed to help the business? Is it really helpful to have the business miss out on potentially significant opportunities just because you couldn’t spare an hour or two?

忽略它? 您将在计划的工作上取得进展,但是您现在还会有许多外部利益相关者突然对您的部门感到愤怒。 此外,技术不应该对业务有所帮助吗? 仅仅因为您不能花一两个小时而错过潜在的重要机会,这真的有帮助吗?

Triage the asks around a planned schedule? Planned interruptions are better than unplanned ones, but you’re still potentially limiting the progress of other departments and forcing them to work around your schedule — not quite as collaborative as one could be.

根据计划时间表对问题进行分类? 计划中的中断要比计划中的中断要好,但是您仍然有可能限制其他部门的进度,并迫使他们按自己的时间表工作-协作程度可能不尽人意。

Imagine if there was a way to prevent these requirements from every reaching you, and to give the other departments tools to pursue these opportunities without your involvement. They’d be able to make internal pivots without having to rely on engineering to perform the work.

试想一下,是否有一种方法可以阻止这些要求每一项都达到您的要求,并提供其他部门的工具来在您不参与的情况下抓住这些机会。 他们将能够进行内部枢纽,而不必依赖工程来执行工作。

If such a solution existed, you’d save a lot of time and be able to focus on more important problems.

如果存在这样的解决方案,您将节省大量时间,并能够专注于更重要的问题。

Enter the rules engine.

输入规则引擎。

什么是规则引擎? (What is a rules engine?)

A rules engine is a system that performs a set of actions based on specific conditions which can be configured during runtime. This means that an effectively set up rules engine would not require engineers to change a system’s business logic.

规则引擎是一种系统,它根据可以在运行时配置的特定条件执行一组操作。 这意味着有效设置的规则引擎将不需要工程师更改系统的业务逻辑。

Engineers build rules-based systems all the time, albeit unconsciously. Every time you code an if-else statement, you are effectively creating a hardcoded rule that is followed by the system.

工程师始终在不知不觉中构建基于规则的系统。 每次编写if-else语句时,都在有效地创建系统遵循的硬编码规则。

You can go a step further and make these systems configurable dynamically. When I say dynamic, I mean that the behavior of the system is not determined by flows coded by engineers, but by configuration through data.

您可以更进一步,使这些系统可以动态配置。 当我说动态时,我的意思是系统的行为不是由工程师编码的流程决定的,而是由数据配置决定的。

These so-called “codeless” systems are not new. Software like Zapier, Hubspot, and IFTTT operate off of the same concepts, as do more technical implementations like Boomi or Drools.

这些所谓的“无代码”系统并不新鲜。 Zapier,Hubspot和IFTTT等软件的运行原理相同,Boomi或Drools等更多技术实现也是如此。

A rules engine is a system that performs a set of actions based on specific conditions which can be configured during runtime.

规则引擎是一种系统,它根据可以在运行时配置的特定条件执行一组操作。

混凝土的脆性 (The fragility of concrete)

Why are rules engines even needed?

为什么甚至需要规则引擎?

By default, most engineers concern themselves on the details of what the rules are of the code they are writing. They were concrete implementations specific to the business use case they are encountering.

默认情况下,大多数工程师关注他们正在编写的代码规则的细节。 它们是特定于他们遇到的业务用例的具体实现。

This makes sense — code does exactly what it says it does, so engineers need to know what needs to be done to write the code properly.

这是有道理的-代码完全按照其声明的方式工作,因此工程师需要知道需要做什么才能正确编写代码。

However, this coupling to the details of the use case makes the code they write churn significantly when the details of the use case changes. While this approach works in many cases, sometimes the rate of change can become overwhelming, especially on smaller teams or more dynamic environments like post-investment startups.

但是,这种与用例细节的耦合使得当用例细节发生变化时,他们编写的代码会明显混乱。 尽管这种方法在很多情况下都可行,但有时变化的速度会变得势不可挡,尤其是在规模较小的团队或更具活力的环境(如投资后的初创企业)中。

It’s easy to see how these things can change. Business logic is implemented to fulfill a requirement in what behavior the software should exhibit. These requirements can come from many sources — business demands, improvements in UX, regulatory needs, technical drivers, etc.

很容易看到这些事情如何发生变化。 实现业务逻辑是为了满足软件应表现出的行为要求。 这些需求可能来自多种来源-业务需求,UX的改进,法规需求,技术驱动因素等。

Examples include:

示例包括:

  • A “welcome” email must be sent 2 hours after a user signs up用户注册后2小时必须发送“欢迎”电子邮件
  • If a payment account holds more than $100,000, over 3 consecutive days, the entire amount must be disbursed immediately如果付款帐户连续3天持有的金额超过$ 100,000,则必须立即全额支付
  • Employees that are a member of this union should accrue vacation time at double the standard rate for 2019, but not 2021.参加工会的员工应以2019年标准费率的两倍加倍休假时间,而不是2021年。

All of these can also vary in levels of stability, or how often the details change.

所有这些都可能在稳定性级别或细节更改频率上有所不同。

For example, a requirement based on data obtained through user analytics may change weekly, whereas a requirement based on a financial regulation may change once every couple of years. A requirement based on a union contract may only change when the contract is renegotiated.

例如,基于通过用户分析获得的数据的需求可能每周更改,而基于财务法规的需求可能每两年更改一次。 基于工会合同的要求只能在重新协商合同后才能更改。

When it does change, the implementation must change alongside of it.

当确实发生更改时,实现必须随之更改。

实现的演变 (The evolution of an implementation)

Let’s examine a hypothetical implementation of the “welcome” email requirement as it evolves over time.

让我们研究一下“欢迎”电子邮件要求随时间变化的假设实现。

A “welcome” email must be sent 2 hours after a user signs up

用户注册后2小时必须发送“欢迎”电子邮件

第一阶段 (The first stage)

Developers can be relied on to do the easiest thing. Most engineers boil business logic down to an if-this-do-that: if this happens, perform this action.

开发人员可以依靠它来做最简单的事情。 大多数工程师将业务逻辑归结为“如果执行此操作”:如果发生这种情况,请执行此操作。

The first (and unfortunately often last) implementation most developers take is the direct approach.

大多数开发人员采用的第一个(不幸的是最后一个)实施方法是直接方法。

It’s so easy — a single line of code can fulfill this requirement:

非常简单-一行代码即可满足此要求:

def on_user_create   WelcomeEmail.send(in: 2.hours)end

第二阶段 (The second stage)

As time passes, the business often demands changes to details that seemed concrete and set in stone in the past.

随着时间的流逝,企业经常要求对过去似乎是具体的,固定的细节进行更改。

Change is a constant, and software is SOFTware for a reason — it has to be malleable to fit the situation and circumstances.

变化是一个常数,而软件是软件是有原因的-它必须具有适应性,以适应具体情况。

What if we discover that 2 hours is too long, and we want to change it to 15 minutes? If we do, an engineer needs to go and change it.

如果我们发现2小时太长,而又想将其更改为15分钟怎么办? 如果这样做,工程师需要去进行更改。

def after_user_create   WelcomeEmail.send(in: 15.minutes)end

Change is a constant, and software is SOFTware for a reason — it has to be malleable to fit the situation and circumstances.

变化是一个常数,而软件是软件是有原因的-它必须具有适应性,以适应具体情况。

第三阶段 (The third stage)

If the business is performing experiments to see what kind of on-boarding leads to the best retention and conversion rates, it’s likely this value will change a lot.

如果企业正在进行实验,以了解哪种入职方式可带来最佳的保留率和转化率,则该价值可能会发生很大变化。

If this happens enough times, the developer will hopefully get smart and move this detail out of the code so it can be configured during runtime.

如果发生这种情况的次数足够多,开发人员将有望变得聪明,并将此细节移出代码,以便可以在运行时对其进行配置。

def after_user_create   WelcomeEmail.send(in: Configuration.get('welcome_email_wait'))end

Configuration.get could access the database, read a configuration file, look at an environment variable, or perhaps even randomly decide. The important factor is that it is now determined at runtime instead of hard-coded.

Configuration.get可以访问数据库,读取配置文件,查看环境变量,甚至可以随机决定。 重要的因素是,它现在是在运行时确定的,而不是硬编码的。

第四阶段 (The fourth stage)

Each individual requirement taken in isolation often ends at the third stage.

孤立地满足的每个单独要求通常在第三阶段结束。

However, if there is a collection of related requirements, patterns can start to emerge which the intuitive engineer can pick up on.

但是,如果有一系列相关需求,则可能会出现一些直观的工程师可以借鉴的模式。

Let’s say the business also wants to send a tips and tricks email. An engineer is likely to code the following implementation, being consistent with prior work:

假设该企业还希望发送提示和技巧电子邮件。 与先前的工作一致,工程师可能会编码以下实现:

def after_user_create   WelcomeEmail.send(in: Configuration.get('welcome_email_wait'))   TipsEmail.send(in: Configuration.get('tips_email_wait'))end

Once again, however, it requires a engineer to add support for the new kind of email.

但是,这再次要求工程师增加对新型电子邮件的支持。

检查演变 (Examining the evolution)

As we’ve seen above — each change is easy and small, but it adds up over time, quite insidiously. It’s easy to see how it can quickly grow out of control in a system where hundreds or thousands of requirements may be implemented in parallel, often under high delivery pressure.

正如我们在上面看到的那样,每个更改都很容易,而且很小,但是随着时间的推移,它会变得非常隐蔽。 很容易看到它如何Swift脱离控制,而该系统通常会在高交付压力下并行执行成百上千的需求。

Even in this simple circumstance, time has caused unrelated emails to be tightly coupled to record lifecycle, which makes systems more complicated.

即使在这种简单的情况下,时间也导致无关的电子邮件与记录的生命周期紧密相关,这使系统更加复杂。

In the above scenario, the developer made the judgement to couple the mechanism to the use case. This means the developer tied together what was being done to how something should be done to why something was being done. They coupled the business domain to the technical domain — the mechanism became tied to the use case.

在上述情况下,开发人员做出了将机制耦合到用例的判断。 这意味着开发商绑在一起正在采取什么东西应该怎么做, 为什么事情正在做。 他们将业务领域与技术领域相结合-机制与用例联系在一起。

They coupled the business domain to the technical domain — the mechanism became tied to the use case.

他们将业务领域与技术领域相结合-机制与用例联系在一起。

When we introduced the tips and tricks email, we essentially had to repeat the implementation. The implementation relied on specific details — namely when something was being done, how long to wait, and what was actually being sent. These details then changed, forcing changes to the implementation (aka. extra work for engineers).

当我们介绍提示和技巧电子邮件时,我们实际上必须重复执行。 该实现依赖于特定的细节,即何时完成某件事,等待多长时间以及实际发送了什么。 然后更改了这些详细信息,迫使更改实现(又称工程师的额外工作)。

细节没关系 (The details don’t matter)

The truth is that these details don’t matter.

事实是,这些细节无关紧要。

From a technical perspective, it shouldn’t matter whether a welcome email is sent 2 hours after the user signs up or 15 minutes after. Nor should it matter that it was a welcome email or a tips and trick email.

从技术角度来看,在用户注册2小时后还是15分钟后发送欢迎电子邮件都没有关系。 不管是欢迎电子邮件还是提示和技巧电子邮件,都没有关系。

That’s the realm of the business — these are merely use cases for the base technology.

那就是业务的境界-这些仅仅是基础技术的用例。

The implementation itself should remain the same — as far as the system should be concerned, it sent a Foobar notification upon creation of a Whatsittoya record, and can use (mostly) the same exact code to send a Fizzbuzz notifcation upon the deletion of a Whatchamacallit record.

实现本身应该保持不变-就系统而言,它在创建Whatsittoya记录时发送了Foobar通知,并且可以使用(大部分)相同的代码在删除Whatchamacallit时发送Fizzbuzz通知记录。

When it is sent or what is being sent are details that just aren’t as concrete. These are the details that should be abstracted away because these are the details that are the most likely to change over time.

何时发送或正在发送的内容并不十分具体。 这些细节应该被抽象掉,因为这些细节最有可能随着时间而改变。

You don’t want to have to engineer something every time a requirement changes. You want to give that power to the business, barring some contractual, security[1], or regulatory requirement.

您不需要每次需求变化时都必须进行工程设计。 您希望将业务授权给业务,除非有合同,安全性[1]或法规要求。

[1] Security also includes job security.

[1]安全性还包括工作安全性。

建立规则引擎 (Building a rules engine)

So, now that we’ve examined the context in which a rules engine would be useful, how do you actually build one?

因此,既然我们已经研究了规则引擎有用的上下文,那么您如何实际构建一个呢?

There’s a lot of ways, but conceptually a minimal rules engine includes the following components:

有很多方法,但是从概念上讲,最小规则引擎包括以下组件:

规则 (Rule)

A rule is a business policy. Within the technical domain of the rules engine, it is a collection of a set of triggers, conditions, and effects that are applied by the rules engine.

规则是一种业务策略。 在规则引擎的技术领域内,它是规则引擎所应用的一组触发器,条件和效果的集合。

触发 (Trigger)

The trigger is the thing that determines whether the engine should attempt to run through a rule or not. In most cases, it is contextual.

触发器是确定引擎是否应该尝试通过规则运行的事物。 在大多数情况下,它是上下文相关的。

In simple systems, it could be a simple string check or even hard-coded, such as a string on a Rule with the value on_create and PaymentAccount to indicate that the rule should only be executed when a record of type PaymentAccount is created.

在简单的系统中,它可以是简单的字符串检查,甚至可以是硬编码的,例如规则上的字符串,其值为on_createPaymentAccount以指示仅当创建PaymentAccount类型的记录时才应执行该规则。

In more complex systems, it could be a full context check that looks at things like whether the user is logged in or the kind of record being worked on.

在更复杂的系统中,它可能是一个完整的上下文检查,它检查诸如用户是否已登录或正在处理的记录类型之类的事情。

健康)状况 (Condition)

The Condition determines if the Rule should be applied in that particular circumstance and on that particular record.

条件确定是否应在该特定情况下以及该特定记录上应用该规则。

It has some minor overlap conceptually with a trigger, but also enough differences to warrant a separate discussion.

从概念上讲,它与触发器有一些细微的重叠,但也有足够的差异,值得单独讨论。

A trigger is more of a generalized determination of whether a rule’s conditions should even be checked, whereas condition is more of an instance-specific check. Smaller systems can potentially fold the trigger in to a a condition, but more complex systems will likely benefit from separating the two.

触发条件更多地是确定是否应检查规则条件的一般确定,而条件更多地是特定于实例的检查。 较小的系统可能会将触发器折叠成一个状态,但是更复杂的系统可能会受益于将两者分开。

The Condition itself will likely have some sort of reference to actual code that performs the check itself, with some parameters to pass in to the function.

Condition本身可能会对执行检查本身的实际代码进行某种形式的引用,并将某些参数传递给函数。

For example, you could store a Condition record in the database that stores the name of the condition class as well as some accompanying parameters. The code could then dynamically initialize the condition class it identifies, passing in the parameters and the record to check against.

例如,您可以在数据库中存储一个条件记录,该记录存储条件类的名称以及一些附带的参数。 然后,代码可以动态初始化它标识的条件类,并传入参数和要检查的记录。

影响 (Effect)

The Effect is what happens once a Rule is triggered and its Conditions pass. It is typically a function or execution of a function. It may be something as simple as setting a field or something as complex as kicking off an entire workflow.

效果是触发规则并通过条件后发生的情况。 它通常是一个函数或函数的执行。 它可能像设置字段一样简单,也可能像启动整个工作流程一样复杂。

Like the Condition, it will likely have some sort of reference to actual code that applies the Effect itself.

像条件一样,它可能会对应用效果本身的实际代码有某种引用。

发动机 (Engine)

Finally, you have the engine itself. This is the thing that will actually perform the bulk of the work. It’ll accept records, load a list of rules, check whether those rules should be applied based on specific triggers and conditions, and then apply the effects of the rules.

最后,您拥有引擎本身。 这实际上将完成大部分工作。 它将接受记录,加载规则列表,检查是否应基于特定的触发器和条件应用这些规则,然后应用规则的效果。

其他一些令人关注的领域 (Some other areas of concern)

In addition to the above components, you’ll also likely encounter secondary areas of concern when building the rules engine. Things like auditing changes to rules, tracking the history of rules being applied, enabling the configuration of rules to specific people, event-based effects, rule DSLs, etc. are all related subsystems, but also outside the scope of the core of the rules engine.

除了上述组件之外,在构建规则引擎时,您还可能会遇到其他需要关注的方面。 诸如审核规则更改,跟踪所应用规则的历史记录,为特定人员启用规则配置,基于事件的效果,规则DSL等之类的东西都是相关子系统,但也超出了规则核心的范围。发动机。

规则引擎的流程 (The flow of a rules engine)

How would this rules engine actually work?

该规则引擎实际上将如何工作?

  • Step 1: Trigger the engine步骤1:触发引擎
  • Step 2: Get the Rules步骤2:取得规则
  • Step 3: Check the Conditions步骤3:检查条件
  • Step 4: Apply the Effects步骤4:套用效果

步骤1:触发引擎 (Step 1: Trigger the Engine)

The first step that occurs is the engine gets triggered. The entry point could be a function Engine#run. This function is passed a record and its associated context (eg. if the record is newly created, or the engine is being called in an update, etc.)

发生的第一步是触发引擎。 入口点可以是Engine#run函数。 向该函数传递一条记录及其关联的上下文(例如,如果是新创建的记录,或者正在更新中调用引擎等)

步骤2:取得规则 (Step 2: Get the Rules)

The engine will get the list of rules that apply for that specific context. Perhaps it will load it in real-time from the database. Maybe it pre-loaded it from a configuration file when the system booted.

引擎将获取适用于该特定上下文的规则列表。 也许它将从数据库中实时加载它。 可能是系统启动时从配置文件中预加载了它。

Either way, these Rules will have associations to Conditions and Effects, which is what the important part is for the next couple of steps.

无论哪种方式,这些规则都将与条件和影响相关联,这是接下来的几个步骤中重要的部分。

步骤3:检查条件 (Step 3: Check the Conditions)

The Condition would be a boolean check that determines whether the Rule’s Effects should be applied or not. If a Rule has multiple Conditions, further boolean logic should be performed to determine how the Conditions are evaluated to determine whether the Rule applies or not (eg. all or nothing, any, quorum).

条件将是布尔检查,确定是否应应用规则的效果。 如果一个规则具有多个条件,则应执行进一步的布尔逻辑以确定如何评估条件以确定该规则是否适用(例如,全部或全部,全部,法定人数)。

步骤4:套用效果 (Step 4: Apply the Effects)

If the Rule’s Conditions pass, it is time to apply the Effects. The Effect itself is arbitrary. You‘ll want to determine how to handle cases in which the application of an Effect failed.

如果规则的条件通过,则是时候应用效果了。 效果本身是任意的。 您将要确定如何处理效果应用程序失败的情况。

Once this happens, the Rule has been applied. You’ve done it!

一旦发生这种情况,便会应用规则。 你完成了!

一个具体的例子 (A concrete example)

Suppose you had to set up a user account to be marked as a “Popular” member once a certain number of views for the profile has been reached. You could theoretically hard-code this, but it would require an engineer to change in the future. Good engineering minimizes the cost and impact of likely future changes.

假设您必须设置一个用户帐户,以便在达到个人资料的特定数量的视图后将其标记为“受欢迎”成员。 从理论上讲,您可以对此进行硬编码,但是将来需要工程师进行更改。 良好的工程设计可将成本和未来可能发生的变化的影响降至最低。

If you had a rule engine that you could use to configure this instead, engineers would not be required.

如果您有可用于配置它的规则引擎,则不需要工程师。

A Rule could be created that:

可以创建一个规则:

  • had the Trigger of view

    有触发的view

  • had a Condition of view_count being greater than 100

    view_count条件大于100

  • had an Effect of setting a field of the user to popular

    具有将用户领域设置为popular

The record would then run automatically through the rules engine, and could also be changed in the future.

然后,该记录将通过规则引擎自动运行,并且将来也可以更改。

样例代码 (Sample code)

Having a hard time conceptualizing this? Not to fear — I’ve created a small Github repository to illustrate some of the concepts here.

很难将其概念化吗? 不用担心-我创建了一个小的Github存储库来说明这里的一些概念。

Note that this isn’t intended to be a production-grade system, but rather a simplified illustration of the above concepts. Actual rules engines have many more moving parts and take into consideration a whole host of other cases.

请注意,这并不是要成为生产级系统,而只是上述概念的简化说明。 实际的规则引擎具有更多的活动部分,并考虑了许多其他情况。

As a final disclaimer: improperly implemented rules engines or rules engines applied outside of the appropriate context can also make your system incredibly complicated and lead to a loss of organizational agility, so be judicious in their usage.

作为最后的免责声明:不正确实施的规则引擎或在适当上下文之外应用的规则引擎也会使您的系统异常复杂,并导致组织敏捷性丧失,因此请谨慎使用它们。

Rules engines are highly useful tools — in the right context. If implemented properly, they can significantly ease development burden and improve the agility of other departments within your organization.

在正确的上下文中,规则引擎是非常有用的工具。 如果实施得当,它们可以大大减轻开发负担并提高组织内其他部门的敏捷性。

翻译自: https://medium.com/swlh/how-to-design-software-rules-engines-adbb098b2d73

软件 规则引擎


http://www.taodudu.cc/news/show-1965611.html

相关文章:

  • 什么是软件质量保证_什么是软件质量?
  • 企业软件是最难编写的软件
  • 中国知名it软件开发外包公司有哪些呢
  • 中国企业软件为什么如此的难
  • 公司财务(书籍学习过程总结)
  • UML概要基础知识(待完善)
  • 4 软件业务分析要点
  • 第三章项目启动
  • 因使用盗版软件赔偿 869 万元 :CIO被开除、罚 15 万元
  • SAP License:财务流程-新
  • 软件流程和管理(四):PMP Stakeholder Management
  • 软件质量管理
  • 软件行业 职位 英文简称
  • 什么是软件质量?
  • 新中大软件显示无法连接服务器,新中大服务器数据库未能连接
  • 软件行业职位
  • 知名的软件公司
  • oracle sap 英克,中普审计软件内置350多个财务软件接口(新)-2015.9.16
  • 软件行业各职位英文缩写
  • 计算机软件行业各职位英文缩写
  • 软件工程复习题
  • 高德地图获取经纬度坐标
  • 通过高德地图api获取地点坐标(以查询物资点为例)
  • android高德地图选取坐标点,【API】高德地图API JS实现获取坐标和回显点标记(示例代码)...
  • 学会提问
  • 图片如何转PDF格式?这些方法值得收藏
  • 只要学会这个PDF压缩方法,压缩PDF不再是难题
  • 1分钟教会你怎么PDF转图片,告别手动截图
  • 办公技巧分享:如何编辑PDF文件内容
  • 学会这个方法,轻松为PDF文件加密,快来码住

软件 规则引擎_如何设计软件规则引擎相关推荐

  1. java风控系统规则引擎_如何设计一套规则引擎系统

    很早之前就想写一篇关于「规则引擎」的文章,但是一直苦于没有时间.刚好最近给团队小伙伴梳理了我设计的引擎的使用和原理,正好借此机会在此写下我们的心得. 「规则引擎」系统一般而言,在风控中使用较多,但是经 ...

  2. cam350菜单怎么切换成中文_电子设计软件CAM350各菜单使用说明(二)

    原标题:电子设计软件CAM350各菜单使用说明(二) 二.Settings 菜单: 1. Unit 设置公英制单位和精确度(小数点后保留位数),需与导入文件制式配否则测量值精确度 不够,鼠标移动也不流 ...

  3. 怎么覆盖默认样式_图形设计软件cdr教程:设置默认字体

    互联网时代,设计师们现在都是用电脑进行设计,那么对字体的需求就比较多,CorelDRAW作为强大的平面设计软件,怎么在其中设置某字体为默认字体呢?对很多新手朋友来说,可能不是很理解. 本文小编介绍在C ...

  4. confirm修改按钮文字_条码设计软件如何调整条形码与条码文字之间的距离

    在条码设计软件中设计条形码的时候,我们可以发现条形码和条码文字之间的距离有些紧密,为了美观,我们可以调整一下条形码与条码文字的间距,具体操作如下: 1.打开条码设计软件,新建标签之后,点击软件左侧的& ...

  5. mysql 规则引擎_为什么要用规则引擎?

    一天,朱斯参加了一场code Review研讨会.会上的一群人正在讨论着如何对祖传代码进行变更,大家你一言,我一语,场面十分热闹! 突然,只见人群中的一个人满面愁容,说道:"昨天在项目中看到 ...

  6. 林期苏曼属性标签编辑_标签设计软件如何设置条码文字分段显示

    在日常生活中我们遇到的条码文字一般都是居中显示的,但是也有分段显示的,如药品标签上的条码文字,那么这个分段的的条码文字在标签设计软件中是如何实现的呢?具体操作如下: 1.打开标签设计软件,在软件中新建 ...

  7. javplayer 使用教程_药物设计软件Sybyl教程(五):绘制分子对接后对接表面

    教程内容: 以SYBYL-X 2.0软件为例,进行分子对接(Surflex-Dock)后创建对接空腔的对接表面教程. 1 视频教程 建议在wifi环境下观看~ 2 图文教程 1.打开对接结果 本期教程 ...

  8. 电脑投屏软件哪个好_电脑绘画软件哪个好?

    电脑绘画软件哪个好?初学漫画怎么选择绘画软件?_漫画培训_绘画培训 这应该是困扰很多漫画小白的问题了吗?初学漫画.绘画应该选择哪一种数字绘画软件?本期小编就给各位小伙伴介绍一下几款画漫画常用的数字绘画 ...

  9. 软件质量保证计划_如何做好软件项目的质量管理?

    保证软件质量,是一个贯穿整个软件生存周期的重要问题.在早期,由于忽视了质量管理,导致软件项目管理的严重问题,以至于在软件开发中出现软件危机.重视软件质量管理,规范软件质量管理体系,对整个软件项目管理起 ...

  10. linux 开源电子软件,linux下开源电子设计软件

    1. 电路模拟器 Qucs http://www.oschina.net/p/qucs 2. 微控制器模拟器 PICsim http://www.oschina.net/p/picsim 3. 电气原 ...

最新文章

  1. ros web_video_server的使用及Python获取实时画面
  2. jQuery源码学习(1)——addClass
  3. 第一篇:构建Mysql服务器
  4. mysql的命令行常用命令_mysql命令行常用命令
  5. 再见 Postman!Apifox 才是 YYDS!
  6. redis主从复制_技术干货分享:一文了解Redis主从复制
  7. Flask中数据库的应用
  8. git查看历史记录及修改内容
  9. 微信小程序相册-笔记1
  10. ThreeJs 学习之旅(十三)—Galaxy Generator(银河系建立)
  11. Long Press(长按功能)
  12. 前端小白-HTML简介
  13. firefox插件安装位置
  14. CC-Proxy配置网络代理服务器
  15. [重磅] 让HTML5达到原生的体验 系列之一 避免切页白屏
  16. 11. K8S资源限制,多账户管理及网络实现
  17. Linux常用命令——telnet命令
  18. php 发送邮箱的stmp服务器
  19. Oracle 10g数据库创建
  20. 细数15款国外的英文开源商城网店系统

热门文章

  1. 高级软考之——系统分析师思维导图(二)
  2. 数学建模(6)典型相关性分析
  3. 电脑应该如何升级bios版本
  4. 中国计算机学会推荐国际学术会议和期刊目录(2019)
  5. MYSQL数据库管理与应用
  6. python实现一个QQ群聊天机器人
  7. 使用PowerDesigner设计数据库保姆级教程
  8. apms阅卷系统服务器,Win 8系统运行APMS阅卷系统的解决办法
  9. nested exception is org.apache.ibatis.executor.ExecutorException: No constructor found in com.chengg
  10. 微信小程序图片全屏显示