Unity文书档案阅读 第一章 入门

那一个改换影响到您如何轻巧的满意那些供给列表。
• It is now clear that the ManagementController class, and any other
clients of the TenantStore class are no longer responsible for
instantiating TenantStore objects, although the example code shown
doesn’t show which class or component is responsible for instantiating
them. From the perspective of maintenance, this responsibility could now
belong to a single class rather than many.

In reality, you will assign different features and components to smaller
groups to work on in parallel.

前边的例证也演说了另三个周边观点关于在你的应用程序的哪个地点使用那么些技艺。最恐怕,ManagementController类存在于应用程序的客商界面层,TenantStore类是数码存款和储蓄层的一某个。它是统筹应用程序的平时方法,以便以往讲不定替换一个层,而不影响到别的层。比方,改变只怕加多新的UI到应用程序中(举例为理念的web
UI创立移动平台的APP)不用修改数据层,或调换上边包车型地铁储存机制,不用改变UI层。使用层构建应用程序有利于将应用程序的相继部分互相分离。你应该尝试确认应用程序在未来或者会不改换的一部分,然后将它们与应用程序的其他部分分离,以便最小化和本地化那些改动的影响。

延时绑定
In some application scenarios, you may have a requirement to support
late binding.

开闭原则注明“软件实体(类、模块、函数等等)应该对扩张开放,对修改关闭”(迈尔,
Bertrand (一九八七). 面向对象软件构造。)
尽管你只怕在类中期维修改代码以修复缺欠,如若您想增加任何新表现到那么些类中,你应该扩展那些类。能够透过遵守开放/密闭原则来满足对你的应用程序扩展对横切关怀的支撑的渴求。譬如。当你增加一组日志记录类到您的应用程序中时,你不该去改换你现存类的贯彻。
The Liskov Substitution Principle

Ideally, you want a mechanism that will enable you to efficiently and
transparently add behaviors to your objects at either design time or run
time without requiring you make changes to your existing classes.

• In order to run unit tests on the Index and Detail methods in the
ManagementController class, you need to instantiate a TenantStore object
and make sure that the underlying data store contains the appropriate
test data for the test. This complicates the testing process, and
depending on the data store you are using, may make running the test
more time consuming because you must create and populate the data store
with the correct data. It also makes the tests much more brittle.

单一职责标准
The single responsibility principle states that a class should have one,
and only one, reason to change. For more information, see the article
Principles of Object Oriented Design by Robert C. Martin1.
In the first simple example shown in this chapter, the
ManagementController class had two responsibilities: to act as a
controller in the UI and to instantiate and manage the lifetime of
TenantStore objects. In the second example, the responsibility for
instantiating and managing TenantStore objects lies with another class
or component in the system.

本章两段代码示例表明什么行使这一尺度。在第三个示范中,高层的ManagementController
类底层的TenantStore
类。这日常限制了在另四个上下文中选取高层类的抉择。

利用双测量检验上的赫赫钻探,亲看Steve Freeman的point/counterpoint
debate(点/对位议论),Nat Pryce和Joshua Kerievsky
IEEE软件(难点:数量:14日3),二〇〇七年11月/ 二月pp.80 – 83。

The Open/Closed Principle

注意,ManagementController类必需实例化二个TenantStore指标或从另各省方获得到TenantStore对象的援引工夫调用GetTenantGetTenantNames方法。

Before you learn about dependency injection and Unity, you need to
understand why you should use them. And in order to understand why you
should use them, you should understand what types of problems dependency
injection and Unity are designed to help you address. This introductory
chapter will not say much about Unity, or indeed say much about
dependency injection, but it will provide some necessary background
information that will help you to appreciate the benefits of dependency
injection as a technique and why Unity does things the way it does.

动机

Loose coupling should be a general design goal for your enterprise
applications.

油滑和可扩张性 Flexibility and extensibility are also often on the list of desirable
attributes of enterprise applications.

Another scenario where late binding can be useful is to enable users of
the system to provide their own customization through a plug-in.

乘机系统变大,和系统的话音寿命边长,维护那八个系统就产生了越来越多的挑战。乃至一时,原集体成员谁自己作主开采的系统不再可用,大概不再记得系统的局地细节。文书档案恐怕过期,恐怕乃至错过。在同期,业务可能须要飞速心动去满意一些十万火急的新职业须要。可维维护性是北狄软件品质,那决定你可以怎么轻易的和如何有效的更新她。你恐怕供给去立异系统,要是先天不足开掘必需整治(换句话说,实践维修爱护),假若某个操作意况的变动供给你再系统中做出退换,可能只要您须求再系统中加多新成效,以满意职业需要(达成的维护)。可保证的体系升高共青团和少先队的狡猾和下落资金。你应该包蕴可维护性作为你叁个企划目的,以及其他诸如可信赖性、安全性和可伸缩性。

For a great discussion on the use of test doubles, see the
point/counterpoint debate by Steve Freeman, Nat Pryce and Joshua
Kerievsky in IEEE Software (Volume: 24, Issue: 3), May/June 2007,
pp.80-83.

以下一些陈说了那一个规律及其与松耦合的关系以及本章开始列出的渴求。

在您读书有关重视注入和Untity之前,你必得明白为何你应当采用它。和为了知道您干吗应该使用它,你应有领会重视注入和Unity能够帮您化解些什么的标题。那么些带领章节讲不会讲太多关于Unity,可能说是不会讲太多关于依赖注入,不过辅导章节会提供部分须要的背景知识,那将力促你欣赏信赖注入的本领,和怎么Unity的行事情势。

独具特殊的优越条件状态下,你须求八个技能,那将使您能够去有效的和透亮地将作为加多到目的,在统一希图时要么运行时都无需你改动现成类。

总结 In this chapter, you have seen how you can address some of the common
requirements in enterprise applications such as maintainability and
testability by adopting a loosely coupled design for your application.
You saw a very simple illustration of this in the code samples that show
two different ways that you can implement the dependency between the
ManagementController and TenantStore classes. You also saw how
the SOLID principles of object-oriented programming relate to the same
concerns.
However, the discussion in this chapter left open the question of how to
instantiate and manage TenantStore objects if the
ManagementController is no longer responsible for this task. The
next chapter will show how dependency injection relates to this specific
question and how adopting a dependency injection approach can help you
meet the requirements and adhere to the principles outlined in this
chapter.

可维护性

In this example, the TenantStore class implements a repository that
handles access to an underlying data store such as a relational
database, and the ManagementController is an MVC controller class that
requests data from the repository.

///<summary>

///房客存储

///</summary>

public class TenantStore
{
    ...
    public Tenant GetTenant(string tenant)
    {
    ...
    }
    public IEnumerable<string> GetTenantNames()
    {
    ...
    }
}

///<summary>

///管理控制器

///</summary>

public class ManagementController
{
    private readonly TenantStore tenantStore;
    public ManagementController()
    {
        tenantStore = new TenantStore(...);
    }
    public ActionResult Index()
    {
        var model = new TenantPageViewData<IEnumerable<string>>(this.tenantStore.GetTenantNames())
        {
            Title = "Subscribers"
        };
        return this.View(model);
    }
    public ActionResult Detail(string tenant)
    {
        var contentModel = this.tenantStore.GetTenant(tenant);
        var model = new TenantPageViewData<Tenant>(contentModel)
        {
            Title = string.Format("{0} details", contentModel.Name)
        };
        return this.View(model);
    }
    ...
}

可测量检验性应该是另一个系统的统一企图指标以及可维护性和敏捷性:二个可测验的系统平日更易于维护,反之亦然。

在切实可行中,你会分配差异的效劳和组件到小组开展交互专门的学业。

When Should You Use a Loosely Coupled Design?

至极担负创造存储实例的类以往能够在传播存款和储蓄实例到顾客在此之前增进横切关怀,如通过使用装饰者格局传递叁个对象达成横切关怀。你无需修改客商类或存款和储蓄类去丰盛协理横切关切,比方日志记录或非常管理。

• Although this simple example shows only a single client class of the
TenantStore class, in practice there may be many client classes in your
application that use the TenantStore class. If you assume that each
client class is responsible for instantiating or locating a TenantStore
object at runtime, then all of those classes are tied to a particular
constructor or initialization method in that TenantStore class, and may
all need to be changed if the implementation of the TenantStore class
changes. This potentially makes maintenance of the TenantStore class
more complex, more error prone, and more time consuming.

If the interface is in a separate project to the implementation, then
the projects that contain the client classes only need to hold a
reference to the project that contains the interface definition.

S:单一任务标准,贰个类应该只有一个产生变化的缘由

常见,你需有在运转时铺排配置这么些特色的本事,在少数情状下,增加性情去管理一个新的横切关怀点到存活应用程序中。

麻痹概略耦合设计的小例子,接口编制程序,和依据注入平常是的消除方案越发错综相连。你应有牢记这么些手艺的含义是在与协理你简化和管制有比比较多类和依赖的特大型复杂应用程序,当然小的应用程序能够发在成大的纷纷应用程序。

Testability

前期绑定的另三个情状中,恐怕是可行的是让客商通过二个插件系统提供自身的定制。

If you use TDD, it may be impractical to run all the tests in the cloud
all of the time because of the time it takes to deploy your application,
even to a local emulator.

虚构到专业必要时常退换,双方在付出应用的时候和在运作产品在此以前,你应有尝试去设计使用,把他做得灵活,所以她能够适应专业在差异的行经和可扩张,所以您能够增加新的特征。

横切关怀 Enterprise applications typically need to address a range of
crosscutting concerns such as validation, exception handling, and
logging.

方法测验驱动的支付(TDD)须求你编写一个单元测验前编辑任何代码来兑现新作用,那样的计划技能的靶子是增高应用程序的身分。

您哪些时候应该使用松散耦合的宏图?
Before we move on to dependency injection and Unity, you should start to
understand where in your application you should consider introducing
loose coupling, programming to interfaces, and reducing dependencies
between classes. The first requirement we described in the previous
section was maintainability, and this often gives a good indication of
when and where to consider reducing the coupling in the application.
Typically, the larger and more complex the application, the more
difficult it becomes to maintain, and so the more likely these
techniques will be helpful. This is true regardless of the type of
application: it could be a desktop application, a web application, or a
cloud application.

public interface ITenantStore
{
    void Initialize();
    Tenant GetTenant(string tenant);
    IEnumerable<string> GetTenantNames();
    void SaveTenant(Tenant tenant);
}
public interface ITenantStoreLogo
{
    void UploadLogo(string tenant, byte[] logo);
}
public class TenantStore : ITenantStore, ITenantStoreLogo
{
    ...
    public TenantStore()
    {
        ...
    }
    ...
}

狡猾和可扩展性也时常是在公司应用理想属性列表中。

Rees代表原则
The Liskov substitution principle in object-oriented programming states
that in a computer program, if S is a subtype of T, then objects of type
T may be replaced with objects of type S without altering any of the
desirable properties, such as correctness, of that program.

In the definition of the ITenantStore interface shown earlier in this
chapter, if you determined that not all client classes use the
UploadLogo method you should consider splitting this into a separate
interface as shown in the following code sample:

It can be a significant challenge to ensure that classes and components
developed independently do work together.

当你在支付大范围(以致中型Mini规模)系统,整个团队还要的劳作在平等的机能和零部件上是不实际的。

下边包车型地铁例证表达了紧密耦合的管控器类直接取决于TenantStore类。那些类可能在分歧的Visual
Studio 项目中。

终极,在此伏彼起依赖注入和Unity此前,大家期待将面向对象编制程序和统一筹算的多少个SOLID原则与到前段时间停止的研商相关联。SOLID是指以下原则的首字母缩写:

面向对象设计标准
Finally, before moving on to dependency injection and Unity, we want to
relate the five SOLID principles of object-oriented programming and
design to the discussion so far. SOLID is an acronym that refers to the
following principles:
• Single responsibility principle
• Open/close principle
• Liskov substitution principle
• Interface segregation principle
• Dependency inversion principle
The following sections describe each of these principles and their
relationship to loose coupling and the requirements listed at the start
of this chapter.

当你陈设和开辟软件系统,牵记到有那一个需要。一些奇特的系统难点和越来越多的司空见惯的靶子。你能够分类一些效果与利益必要,和局部非作用要求(或品质属性)。这一体的渴求将违反每三个两样的系统。一组要求陈述下是常常须求,极度是职业(LOB)软件系统相对较长的料想寿命。他他们不都自然会是不能缺少的对于每五个系统开垦,可是你能够明确的是,他们有的将会在你的等级次序工作上的供给列表中。

开闭原则
The open/closed principle states that “software entities (classes,
modules, functions, and so on) should be open for extension, but closed
for modification” (Meyer, Bertrand (1988). Object-Oriented Software
Construction.)
Although you might modify the code in a class to fix a defect, you
should extend a class if you want to add any new behavior to it. This
helps to keep the code maintainable and testable because existing
behavior should not change, and any new behavior exists in new classes.
The requirement to be able to add support for crosscutting concerns to
your application can best be met by following the open/closed principle.
For example, when you add logging to a set of classes in your
application, you shouldn’t make changes to the implementation of your
existing classes.

第3个代码示例中所示的主意是贰个用到接口的麻痹大要耦合设计的事例。要是大家能够去除二个类之间的直白重视关系,它减弱耦合等第,而且有助于进步可维护性、可测验性、灵活性和解决方案的可扩充性。
What the second code sample doesn’t show is how dependency injection and
the Unity container fit into the picture, although you can probably
guess that they will be responsible for creating instances and passing
them to client classes. Chapter 2 describes the role of dependency
injection as a technique to support loosely coupled designs, and Chapter
3 describes how Unity helps you to implement dependency injection in
your applications.

在第一个示范代码中,ManagementController 类现在依据ITenantStore
抽象,TenantStore 类也是那样。
Summary

Flexibility and Extensibility

For a large enterprise system, it’s important to be able to manage
crosscutting concerns such as logging and validation in a consistent
manner. I often need to change the logging level on a specific component
at run time to troubleshoot an issue without restarting the system.

这种措施你不能选择延时绑定,应为顾客端类编写翻译直接采纳TenantStore类。
• If you need to add support for a crosscutting concern such as logging
to multiple store classes, including the TenantStore class, you would
need to modify and configure each of your store classes independently.

若果你须求加上援救横切关心,如登入到几个存款和储蓄类,包含TenantStore类,你将急需修改和布署你各个独立的存款和储蓄类。
The following code sample shows a small change, the constructor in the
client ManagementController class now receives an object that implements
the ITenantStore interface and the TenantStore class provides an
implementation of the same interface.

在本章中,您曾经领悟了怎么通过为你的应用程序选拔松耦合设计来解决公司应用程序中的一些科学普及必要,如可维护性和可测量试验性。您在代码示例中看看了一个极其轻巧的例证,它显得了三种差异的办法,您能够实现ManagementControllerTenantStore类之间的依赖性关系。别的你也看看面向对象SOLID原则如何安排涉及那几个关切。

未有兼具系统要求延时绑定必要,它一般要求援救一个特定的应用程序的作用,如定制使用插件架构。

担保险单独开荒的类和零部件在一块儿专门的职业大概是叁个豪杰的挑衅。

于今能够知道的是ManagementController类和其余其他TenantStore类客商端不再实负担例化TenantStore目的,纵然所出示的身体力行代码不能够显示哪个类或机件是担负实例化他们。从保卫安全的角度,这么些权利显示属于贰个类,并非多少个类。
• It’s now also clear what dependencies the controller has from its
constructor arguments instead of being buried inside of the controller
method implementations.

除此以外,你能够经过应用布署或预订系统扫描文件系统上的特定岗位的模块通告系统去选用一定开垦。

你也许在应用程序的浩大不一世界急需那个功用何况你会期待在贰个标准中贯彻,一致的格局来压实系统的可维护性。

This change has a direct impact on how easily you can meet the list of
requirements.

Again, you can instruct the system to use a specific customization by
using a configuration setting or a convention where the system scans a
particular location on the file system for modules to use。

Motivations
When you design and develop software systems, there are many
requirements to take into account. Some will be specific to the system
in question and some will be more general in purpose. You can categorize
some requirements as functional requirements, and some as non-functional
requirements (or quality attributes). The full set of requirements will
vary for every different system. The set of requirements outlined below
are common requirements, especially for line-of-business (LOB) software
systems with relatively long anticipated lifetimes. They are not all
necessarily going to be important for every system you develop, but you
can be sure that some of them will be on the list of requirements for
many of the projects you work on.

当今能够运用延时绑定,因为顾客类只引用ITenantStore接口类型。应用程序能够在运维时创立接口的兑现指标,大概基于配置安装将对象传递给客商类。比方,应用程序能够依赖Web.config文件中的配置创立SQLTenantStore实例或BlobTenantStore
实例,并传播到ManagementController类的构造函数中。
• If the interface definition is agreed, two teams could work in
parallel on the store class and the controller class.

The ManagementController class depends on the specific, concrete
TenantStore class.

Dependency Inversion Principle

在我们承继反转注入和Unity在此之前,你应有初露掌握在您的采用中哪个地方应该思考引进松散耦合,设计接口,和收缩类之间的依靠。我们在前一节中陈说的主要条件是可维护性,,这频繁提示何时和有个别地点思量收缩应用程序的耦合性。平日,大型复制应用程序,就变得更复杂,所以更有非常大概率那么些技能是便民的。那是真正,无论应用程序的体系:它大概是一个桌面应用程序,三个web应用程序,或二个云应用程序。
At first sight, this perhaps seems counterintuitive. The second example
shown above introduced an interface that wasn’t in the first example, it
also requires the bits we haven’t shown yet that are responsible for
instantiating and managing objects on behalf of the client classes. With
a small example, these techniques appear to add to the complexity of the
solution, but as the application becomes larger and more complex, this
overhead becomes less and less significant.

Loose coupling doesn’t necessarily imply dependency injection, although
the two often do go together.

譬如说,一些门类是测量试验云端应用,你不能够不安插利用到云端情况,况兼在云端运转测量检验。

public interface ITenantStore
{
    void Initialize();
    Tenant GetTenant(string tenant);
    IEnumerable<string> GetTenantNames();
    void SaveTenant(Tenant tenant);
    void UploadLogo(string tenant, byte[] logo);
}
public class TenantStore : ITenantStore
{
    ...
    public TenantStore()
    {
    ...
    }
    ...
}
public class ManagementController : Controller
{
    private readonly ITenantStore tenantStore;
    public ManagementController(ITenantStore tenantStore)
    {
        this.tenantStore = tenantStore;
    }

    public ActionResult Index()
    {
    ...
    }
    public ActionResult Detail(string tenant)
    {
    ...
    }
    ...
}

• It is now possible to use late binding because the client classes only
reference the ITenantStore interface type. The application can create an
object that implements the interface at runtime, perhaps based on a
configuration setting, and pass that object to the client classes. For
example, the application might create either a SQLTenantStore instance
or a BlobTenantStore instance depending on a setting in the web.config
file, and pass that to the constructor in the ManagementController
class.

Not all systems have a requirement for late binding. It is typically
required to support a specific feature of the application such as
customization using a plug-in architecture.

In this type of scenario, you may decide to use test doubles (simple
stubs or verifiable mocks) that replace the real components in the cloud
environment with test implementations in order to enable you to run your
suite of unit tests in isolation during the standard TDD development
cycle.

越多音讯
All links in this book are accessible from the book’s online
bibliography available at: http://aka.ms/unitybiblio

It is very hard to make existing systems more maintainable. It is much
better to design for maintainability from the very start.

第四个代码示例未有出示是什么借助注入和Unity容器符合,就算你大约猜中他们担任创立实例并传递他们到顾客类。第二章描述了角色关于依赖注入技能去协理松散耦合设计,和第三张陈述Unity怎么样帮衬您在应用程序中贯彻依赖注入。

This chapter introduces a lot of requirements and principles. Don’t
assume that they are all relevant all of the time. However, most
enterprise systems have some of the requirements, and the principles all
point towards good design and coding practices

More Information

譬喻说,你可能必要把你的使用从本土运维变为云端运行。

You can use declarative configuration to tell the application to use a
specific module at runtime.

在这么些方案类型里面,你只怕接纳双测量检验(轻易的票根或可甄别的模拟)代替真正的零部件和测验的落实在云景况中为了让你能够运行单元测量检验套件在切断标准的TDD开垦周期。
Testability should be another of the design goals for your system along
with maintainability and agility: a testable system is typically more
maintainable, and vice versa.

叁个可测量检验系统是贰个得以使您有效测验系统中的各类部分。设计和编辑有效的测验能够正确的设计和编写制定测量试验应用代码,特别是系统变大和特别头昏眼花。

本书中的全数链接均可从本书的在线参谋书目获得,网站为:http://aka.ms/unitybiblio

Late binding is useful if you require the ability to replace part of
your system without recompiling.

L:Rees替换原则,任何基类能够出现的地方,子类一定能够出现

Maintainability
As systems become larger, and as the expected lifetimes of systems get
longer, maintaining those systems becomes more and more of a challenge.
Very often, the original team members who developed the system are no
longer available, or no longer remember the details of the system.
Documentation may be out of date or even lost. At the same time, the
business may be demanding swift action to meet some pressing new
business need. Maintainability is the quality of a software system that
determines how easily and how efficiently you can update it. You may
need to update a system if a defect is discovered that must be fixed (in
other words, performing corrective maintenance), if some change in the
operating environment requires you to make a change in the system, or if
you need to add new features to the system to meet a business
requirement (perfective maintenance). Maintainable systems enhance the
agility of the organization and reduce costs.Therefore, you should
include maintainability as one of your design goals, along with others
such as reliability, security, and scalability.

Small examples of loosely coupled design, programming to interfaces, and
dependency injection often appear to complicate the solution. You should
remember that these techniques are intended to help you simplify and
manage large and complex applications with many classes and
dependencies. Of course small applications can often grow into large and
complex applications.

Late Binding

上边代码示例呈现了小的变型,现在在顾客端ManagementController类构造函数抽出四个目的达成ITenantStore接口,并且TenantStore类提供了ITenantStore接口的贰个贯彻。

• Introducing the ITenantStore interface makes it easier to replace the
store implementation without requiring changes in the client classes
because all they expect is an object that implements the interface.

以此章节初次接触部分须求和规格。不要假使所有的时候候他们都以全然关联的。无论如何,超越八分之四集团制度有一部分如此的须求和那么的口径都指向好的统一筹算和代码标准。

D:依赖倒置原则,高档案的次序的模块不应有依据于低档次的模块,他们都应该依附于肤浅。抽象不应该借助于现实落到实处,具体落到实处应有依据于肤浅。

三个轻松易行的例证
The following example illustrates tight coupling where the
Management-Controller class depends directly on the TenantStore class.
These classes might be in different Visual Studio projects.

在本指南开中学ManagementControllerTenantStore
类被用于各个方式。就算ManagementController类是二个ASP.NET MVC
调整器,你没有必要随着精通MVC。无论怎么着,这么些事例是刻意看起来像你就要系统系统中相见的类,非常是第3章的实例。

Unity很难使现有系统更易于维护。Unity是从一同首为可维护性一大波越来越好的规划。

即便您有用测量检验驱动开荒,它只怕否再任几时间在云端运转具备的测验,因为在哪些时候它在计划布署你的施用,以至是本地当地模拟器。

为了运维ManagementController类中的IndexDetail主意的单元测量检验,为了这一个测量检验你要求实例化TenantStore指标和布局蕴含可信测量试验数据的最底层的数据存款和储蓄。那是三个纵横交错的测验进程,而且依照你所采纳的数量存款和储蓄,只怕运维测量检验更麻烦,因为你必需为数量存储创造并填写正确的数额。那也使得测验特别虚弱。
• It is possible to change the implementation of the TenantStore class
to use a different data store, for example Windows Azure table storage
instead of SQL Server. However, it might require some changes to the
client classes that use TenantStore instances if it was necessary for
them to provide some initialization data such as connection strings.

Principles of Object-Oriented Design

本章第二段代码注脚,假设您将ITenantStore接口的另外完成传递给它,ManagementController类应该继续按预想工作。那些实例使用接口类型作为传递给ManagementController
类构造函数的门类,一样你能够使用抽象类型。
Interface Segregation Principle

A Simple Example

接口隔断原则
The interface segregation principle is a software development principle
intended to make software more maintainable. The interface segregation
principle encourages loose coupling and therefore makes a system easier
to refactor, change, and redeploy. The principle states that interfaces
that are very large should be split into smaller and more specific ones
so that client classes only need to know about the methods that they
use: no client class should be forced to depend on methods it does not
use.

借助于倒置原则
The dependency inversion principle states that:
• High-level modules should not depend on low-level modules. Both should
depend on abstractions.
• Abstractions should not depend upon details. Details should depend
upon abstractions.
The two code samples in this chapter illustrate how to apply this
principle. In the first sample, the high-level ManagementController
class depends on the low-level TenantStore class. This typically
limits the options for re-using the high-level class in another
context.
In the second code sample, the ManagementController class now has a
dependency on the ITenantStore abstraction, as does the
TenantStore class.
依傍倒置原则表明:

Parallel Development

麻痹大体耦合应该是你的公司应用程序的总规划目标。

那章中率先个简易的演示展现ManagementController
类有四个任务:UI中的行为调节和TenantStore对象的实例化和周的期管理。在其次个示范中,实例化和管制TenantStore对象的职责在于系统中的另一个类或机件。

For example, for some types of testing on a cloud-based application you
need to deploy the application to the cloud environment and run the
tests in the cloud.

Methodologies such as test-driven development (TDD) require you to write
a unit test before writing any code to implement a new feature and the
goal of such a design technique is to improve the quality of your
application.

不过,本章斟酌遗留三个标题,假设ManagementController不再承担那些职分,那么什么样实例化和治本TenantStore
对象。在下一章将会展现选用依赖注入如何与具象难点有关和使用信赖注入方法怎么样援救您满意要求并服从本章中概述的准则。

The list of requirements in the previous section also includes
crosscutting concerns that you might need to apply across a range of
classes in your application in a consistent manner. Examples include the
concerns addressed by the application blocks in Enterprise Library
(http://msdn.microsoft.com/entlib) such as logging, exception
handling, validation, and transient fault handling. Here you need to
identify those classes where you might need to address these
crosscutting concerns, so that responsibility for adding these features
to these classes resides outside of the classes themselves. This helps
you to manage these features consistently in the application and
introduces a clear separation of concerns.

ManagementController 类信赖细节,信赖具体的TenanStore类。
If you refer back to the list of common desirable requirements for
enterprise applications at the start of this chapter, you can evaluate
how well the approach outlined in the previous code sample helps you to
meet them.
一旦您想起这一章开始集团应用共同的供给列表,你能够评估办法概述在后面包车型大巴代码示例支持你去满意他们。

下个章节,章节2“正视注入”将显得你怎么信赖注入能够援助你满意本章概述的渴求,和上面章节
章节3“注重注入和Unity”,展示Unity怎么着帮您兑现依附注入方法在您的主次中。

Given that business requirements often change, both during the
development of an application and after it is running in production, you
should try to design the application to make it flexible so that it can
be adapted to work in different ways and extensible so that you can add
new features.

例如接口定义一致,八个团体能够并行工作存款和储蓄类和调控器类。
• The class that is responsible for creating the store class instances
could now add support for the crosscutting concerns before passing the
store instance on to the clients, such as by using the decorator pattern
to pass in an object that implements the crosscutting concerns. You
don’t need to change either the client classes or the store class to add
support for crosscutting concerns such as logging or exception handling.

在本章前边所示的ITenantStore接口的定义中,假设分明不是装有的客商端类都施用UploadLogo方法,您应该思量将其拆分为三个独自的接口,如上边包车型大巴代码示例所示:

For example, you may need to convert your application from running
on-premises to running in the cloud.

为了大商铺系统,首要的是能力所能达到处理横切关心点,如日志记录和声明以同一的格局。笔者平常供给改变记录品级在三个一定的零件在运转时消除难点而没有要求重新启航系统。

Often, you need the ability to configure these features at runtime and
in some cases, add features to address a new crosscutting concern to an
existing application.

如此的设计才具也可以扶持您扩张你的单元测验覆盖率,减弱回归的只怕性,和使重构更简便易行。

公司应用程序平时需求化解一多种的横切关注点,如验证、分外管理和日志记录。

The ManagementController and TenantStore classes are used in various
forms throughout this guide. Although the ManagementController class is
an ASP.NET MVC controller, you don’t need to know about MVC to follow
along. However, these examples are intended to look like the kinds of
classes you would encounter in a real-world system, especially the
examples in Chapter 3.

纵然这些大约的亲自过问仅仅突显二个客商端类属于TenantStore类,在推行中恐怕有非常多客商端类在你的应当程序中央银行使TenantStore类。借令你感觉各个顾客端类担当在运作时实例化或一定TenantStore指标,然后全部这么些类都要绑定到TenantStore类的构造函数货实例化方法,倘诺TenantStore类更换的话你恐怕整个都亟需修改。那说不定使得TenantStore类的为维护性越发目眩神摇、更易于出错,并且更加的艰苦。

相互之间开辟 When you are developing large scale (or even small and medium scale)
systems, it is not practical to have the entire development team working
simultaneously on the same feature or component.

In the second code sample shown in this chapter, the
ManagementController class should continue to work as expected if you
pass any implementation of the ITenantStore interface to it. This
example uses an interface type as the type to pass to the constructor of
the ManagementController class, but you could equally well use an
abstract type.

For example, your application might support multiple relational
databases with a separate module for each supported database type.

运作测量检验也会损耗财富和时间,因为急需在展示环节中测量试验。

为了利用不一样的数目存款和储蓄恐怕须求更换TenantStore类的兑现,举个例子Windows
Azure
表存储,而不是SQLServer。然则,假如它是须要的让他们提供部分初步化数据,比方总是字符串,它可能要求修改部分运用TenantStore实例的类顾客端。
• You cannot use late binding with this approach because the client
classes are compiled to use the TenantStore class directly.

假如接口在单独的连串中贯彻,含有客商类的连串只须求援引蕴涵接口定义的品类。
• It is now also possible that the class responsible for instantiating
the store classes could provide additional services to the application.
It could control the lifetime of the ITenantStore instances that it
creates, for example creating a new object every time the client
ManagementController class needs an instance, or maintaining a single
instance that it passes as a reference whenever a client class needs it.

后天也清楚调整器的依赖是它的构造函数参数,并非在调节器的实现格局内部。
• To test some behaviors of a client class such as the
ManagementController class, you can now provide a lightweight
implementation of the ITenantStore interface that returns some sample
data. This is instead of creating a TenantStore object that queries the
underlying data store for sample data.

麻痹轮廓耦合併不一定意味着信赖注入,索然两个经常在共同利用。

O:开放条件,对扩大开放,对修改关闭

The approach shown in the second code sample is an example of a loosely
coupled design that uses interfaces. If we can remove a direct
dependency between classes, it reduces the level of coupling and helps
to increase the maintainability, testability, flexibility, and
extensibility of the solution.

你能够用发明配置去报告应用在运作去行使一定的模块。

率先影像,那说不定疑似违反直觉的:下边所述的第二事例引入了接口并不是率先个例证,它还索要一些大家还没显示的承受实例化和保管顾客类的对象。用二个小例子,那几个技巧的行使增加了解决的方案的头眼昏花,但随着应用程序变得越来越大、更扑朔迷离,这种(复杂性)费用变得特别不显着。

譬喻说,你的运用支撑两种关周详据库,为每三个援救数据库类型用三个单独的模块。

延时绑定是平价的,假设你须要在你系统没有须要另行编写翻译而转变零件。

选用双测量检验是很好的点子去承接保险你能够在付出进程中穿梭的运维你的单元测量试验。无论怎么着你不能不依旧丰盛的在实际遭遇中测量检验你的利用。

纯净职务标准表明类应该有叁个且唯有七个说辞去改变。更加多消息请看罗Bert C.
马丁1些的面向对象设计的著作。

在局地选用清洁中,你能够有延时绑定的要求。

However, as part of your testing processes you should also incorporate
other types of tests such as acceptance tests, integration tests,
performance tests, and stress tests.

  • 高层模块不该借助底层模块。都应有依赖抽象。
  • 虚幻不该依附细节。细节应该借助抽象。

介绍ITenantStore接口使它更简短的交替存款和储蓄完成,而无需更换客户类,因为他们供给的是多个达成了接口的靶子。

Single Responsibility Principle

Such design techniques also help to extend the coverage of your unit
tests, reduce the likelihood of regressions, and make refactoring
easier.

Using test doubles is a great way to ensure that you can continuously
run your unit tests during the development process. However, you must
still fully test your application in a real environment.

Rees代表原则在面向对象编制程序中写明,在Computer程序,假若ST的子类,那么T类型的靶子能够被替换到S类型的对象而不会改变任何期待值,比如程序的不错。

Crosscutting Concerns

可测验性
A testable system is one that enables you to effectively test individual
parts of the system. Designing and writing effective tests can be just
as challenging as designing and writing testable application code,
especially as systems become larger and more complex.

至今也大概承受实例化的类存款和储蓄类可以提供额外的服务应用程序。它能够管理ITenantStore实例的生命周期,它创造了,举例创立新指标每便客商ManagementController类都必要实例化,大概保卫安全个纯粹实例,它传到援引,每当客商类需求它时。

纵然这种办法是你能够缩小项目全数岁月,它利用了额外的纷纭:你必得管理四个小组还要保障您能够整合不一样小组开辟的行使组件在共同并能常常办事。

You may need these features in many different areas of the application
and you will want to implement them in a standard, consistent way to
improve the maintainability of the system.

The next chapter, Chapter 2, “Dependency Injection,” will show you how
dependency injection can help you meet the requirements outlined in this
chapter, and the following chapter, Chapter 3, “Dependency Injection
with Unity,” shows how Unity helps you to implement the dependency
injection approach in your applications.

唯独,就如有的您的测验进程你应该也隐含别的种类的测量试验举例检验收下测量试验、综合测量试验、质量测量试验、和压力测量检验。
Running tests can also cost money and be time consuming because of the
requirement to test in a realistic environment.

接口隔离原则是一种意在使软件更易维护的软件开垦原则。接口隔开分离原则鼓劲松散耦合,并使系统更易重构、改造和重新铺排。原则注脚一点都一点都不小的接口应该拆分成小的明确性的接口,那样客户类仅仅要求了然有关她们选拔的不二等秘书籍:未有顾客类应该被迫依赖他们不适用的情势。

The previous example also illustrates another general point about where
it is appropriate to use these techniques. Most likely, the
ManagementController class exists in the user interface layer in the
application, and the TenantStore class is part of the data access layer.
It is a common approach to design an application so that in the future
it is possible to replace one tier without disturbing the others. For
example, replacing or adding a new UI to the application (such as
creating an app for a mobile platform in addition to a traditional web
UI) without changing the data tier or replacing the underlying storage
mechanism and without changing the UI tier. Building the application
using tiers helps to decouple parts of the application from each other.
You should try to identify the parts of an application that are likely
to change in the future and then decouple them from the rest of the
application in order to minimize and localize the impact of those
changes.

在此地例子中,TenantStore类实现了一个库来管理访谈多个平底数据存款和储蓄库,如关全面据库,ManagementController是MVC调控器类,他从存储库中呼吁数据。

Although this approach enables you to reduce the overall duration of the
project, it does introduce additional complexities: you need to manage
multiple groups and to ensure that you can integrate the parts of the
application developed by different groups to work correctly together.

测量检验客商类的一部分作为,比如ManagementController
类,你现在得以提供两个轻量级的ITenantStore接口实现再次来到一些样本数量。那是询问实际不是创设TenantStore目的底层数据存款和储蓄的样书数量。

Note that the ManagementController class must either instantiate a
TenantStore object or obtain a reference to a TenantStore object from
somewhere else before it can invoke the GetTenant and GetTenantNames
methods.

I:接口隔断原则,顾客端不应有借助它没有须要的接口;二个类对另三个类的依赖应该创建在十分小的接口

前方部分中的须求列表还满含横切关切,您或然必要以同一的方法在应用程序的一体系类中采纳。示例包涵公司库(http://msdn.microsoft.com/entlib)中的应用程序块所减轻的主题材料,举例日志记录,格外管理,验证和瞬态故障管理。在那边,你供给确定那多少个你恐怕要求化解那个横切关怀的类,所以担任在类本人之外增加性情到那一个类。那推进你在应用程序中一样地管理那个功能,并引进显著的关心点分离。

相关文章