没有合适的资源?快使用搜索试试~ 我知道了~
首页架构微软.NET企业解决方案:实战指导与设计模式
架构微软.NET企业解决方案:实战指导与设计模式
需积分: 3 8 下载量 4 浏览量
更新于2024-08-01
收藏 8.44MB PDF 举报
"《企业级Microsoft .NET解决方案架构》是由Dino Esposito和Andrea Saltarello合著的一本书,由Microsoft Press出版于2008年10月15日。该书针对日益复杂的企业和用户需求,提供了关键的指导和支持。书中强调了在设计软件解决方案时,如何通过明确的模式和实践来应对隐含的挑战,从而确保软件架构的完整性。 作者们分享了他们在企业级和面向服务开发领域的丰富实践经验,深入探讨了创建更高效解决方案的模式、原则和技术。书中特别关注了模型化技术,这些技术确保架构能够充分且明确地满足用户需求。书中涵盖了基础概念,如统一建模语言(UML)和设计模式,以及核心系统架构的各个层面,包括业务层、服务层、数据访问层和表现层。此外,作者还介绍了微软.NET框架和Microsoft Visual Studio等具体工具的使用,提供了实用的代码示例和专家见解,读者可以直接应用于自己的.NET企业级解决方案。 该书的目的是提供一个结构化的、实际的方法来解决软件复杂性问题,帮助读者理解和掌握在处理大型、复杂的企业环境中设计和构建稳健的.NET应用的策略。通过学习这本书,读者不仅可以提升架构设计能力,还能掌握如何利用最新的开发工具和技术来满足企业级用户的具体需求,从而推动项目的成功实施。"
资源详情
资源推荐
The same principle of offering multiple views from distinct viewpoints lies behin d
another vendor-specific model for architectural description—IBM/Rational's 4+ 1
views model. The model defines four main views—nearly equivalent to UM L
diagrams. These views are as follows :
The logical view , which describe component s
The process view , which describes mapping and
dependencies
The development view , which describes classe s
The physical view , which (if necessary) describes mapping
onto hardwar e
The fifth, partially redundant, view is the scenario view, which is specific to us e
cases.
Validating the Architecture
How would you validate the design to ensure that stakeholders' concerns are properly addressed ?
There's no magic wand and no magic formulas that take a more or less formal definition of an architecture as inpu t
and tells you whether it is appropriate for the expressed requirements. To validate the design of a system, yo u
can only test it—in various ways and at various levels .
So you will perform unit tests to validate single functionalities, and you will perform integration tests to see how th e
system coexists with other systems and applications. Finally, you'll run acceptance tests to verify how users actuall y
feel about the application and whether the application provides the services it was created for. (Testing is one of th e
key topics of Chapter 3 , "Design Principles and Patterns.")
What's Architecture and What's No t
When you think about creating or defining the architecture of a software system, you first try to identify a possibl e
collection of interacting components that, all together, accomplish the requested mission. In international standards ,
there's no mention for any methodology you should use to decompose the system into more detailed pieces. Let' s
say that in the first step you a get a conceptual architecture and some different views of it. In a second step, yo u
need to get closer to a functional and physical architecture. How you get there is a subjective choice, although a
top-down approach seems to be a very reasonable strategy. You decompose components into smaller and smalle r
pieces, and from there you start building .
No System Is a Monolith
We've been told that, once upon a time, any piece of software was a monolith with an entry point and finish point .
The introduction of structured programming, and the concept of a subroutine , in the early 1970s started shoulderin g
such monoliths out of the way.
Since then, many software systems have been designed as a graph of components communicating in various way s
and having various levels of dependency. In practical terms, designing a system consists of expanding the Syste m
element that was shown in Figure 1-1 into a graph of subsystems and defining communication policies and rules fo r
each of them.
The process of breaking down these details should ideally continue until you have described in detail the structur e
and relationships for the smallest part of the system. Although fully completing the breakdown process up front is ke y
for constructing habitable buildings, it is not that necessary for building software .
The actual implementation of the breakdown process depends on the methodology selected for the project—th e
more you are agile , the more the breakdown process is iterative and articulated in smaller and more frequent steps .
(We'll return to the topic of methodologies later in the chapter. )
The output of the breakdown process is a set of specifications for the development team. Also, the content an d
format of the specifications depend on the methodology. The more you are agile, the more freedom and
independence you leave to developers when implementing the architecture .
Defining the Borderline Between Architecture and Implementatio n
The constituent components you identified while breaking down the system represent logical functions to b e
implemented in some way. The design of components, their interface, their responsibilities, and their behavior ar e
definitely part of the architecture. There's a border, though, that physically separates architecture fro m
implementation.
This border is important to identify because, to a large extent, it helps to define roles on a development team. I n
particular, it marks the boundary between architects and developers. Over the years, we learned that architects an d
developers are not different types of fruit, like apples and oranges. They are the same type of fruit. However, if the y
are apples, they are like red apples and green apples. Distinct flavors, but not a different type of fruit. And neithe r
flavor is necessarily tastier .
You have arrived at the border between architecture and implementation when you reach a black box of behavior . A
black box of behavior is just a piece of functionality that can be easily replaced or refactored without significan t
regression and with zero or low impact on the rest of the architecture. What's above a black box of behavior is likel y
to have architectural relevance and might require making a hard-to-change decision .
What's our definition of a good architecture? It is an architecture in which all hard-to-change decisions turn out to b e
right.
Dealing with Hard-to-Change Decision s
There are aspects and features of a software system that are hard (just hard , not impossible ) to change once yo u
have entered the course of development. And there are aspects and features that can be changed at any tim e
without a huge effort and without having a wide impact on the system .
In his book Patterns of Enterprise Application Architectur e (Addison-Wesley, 2002), Martin Fowler puts it quit e
simply:
If you find that something is easier to change than you once thought, then it's no longe r
architectural. In the end architecture boils down to the important stuff—whatever that is .
To sum it up, we think that under the umbrella of the term architecture falls everything you must take seriously at
quite an early stage of the project. Architecture is ultimately about determining the key decisions to make and the n
making them correctly.
Architecture Is About Decision s
When we talk about hard architectural decisions, we are not necessarily referring to irreversible decisions abou t
design points that can be difficult and expensive to change later. Hard-to-change decisions are everywhere an d
range from the definition of a conceptual layers to the attributes of a class .
To illustrate our point, let's go through a few different examples of architectural points that can run into budget limit s
and deadlines if you have to touch them in the course of the project .
Changing the Organization of the Business Logi c
In Chapter 4 , "The Business Layer," we'll examine various approaches to organizing the business logic in th e
context of a layered system. Possible approaches for the design of the business logic include transaction script, tabl e
module, active record, and domain model. The selection of a pattern for the business logic is an excellent example o f
a design choice to be made very, very carefully. Once you have opted for, say, table module (which means ,
essentially, that you'll be using typed DataSets to store an application's data in the business logic layer), moving t o
an object model (for example, using the LINQ-to-SQL or Entity Framework object model) is definitely hard an d
requires nontrivial changes in the data access layer and in the application (service) layer, and probably also in th e
presentation layer. If you need to change this decision later in the project, you enter into a significant refactoring o f
the whole system.
Switching to a Different Librar y
Suppose you developed some functionality around a given library. One day, the client pops up and lets you kno w
that a new company policy prevents the IT department from buying products from a given vendor. Now you have a
new, unexpected nonfunctional requirement to deal with .
A change in the specifications might require a change in the architecture, but at what cost? In such a case, you hav e
to comply with the new list of requirements, so there's not much you can do .
In the best case, you can get a similar tool from an authorized vendor or, perhaps, you can build a similar too l
yourself. Alternatively, you can consider introducing a radical change into the architecture that makes that librar y
unnecessary.
We faced an analogous situation recently, and the type of library was an Object/Relational mapping tool. With, say, a
UI control library, it would have been much simpler to deal with. Replacing an Object/Relational mapping tool is no t
easy; it is a task that can be accomplished only by getting another tool from another vendor. Unfortunately, thi s
wasn't possible. In other words, we were left to choose between either of two unpleasant and painfu l
options: writing our own Object/Relational mapping tool, or rearchitecting the middle tier to use a different (and muc h
simpler) object model .
With over 500 presenters in the Model View Presenter–based user interface directly consuming the object model ,
having to make this decision was our worst nightmare. We knew it would require a huge amount of work on th e
middle tier, consuming both financial resources and time. We lobbied for more time and successfully stretched th e
deadline. Then we built our own tailor-made data access layer for a domain model. (After you've read Chapter 6 ,
"The Data Access Layer," you'll have a clear picture of what this all means. )
Changing the Constructor's Signatur e
Don't think that architecture is only about high-level decisions like those involving the design and implementation o f
parts of the middle tier. A requested change in the signature of a class constructor might get you in a fine mess, too .
Imagine a scenario where you handle an Order class in your application's object model. You don't see any reason t o
justify the introduction of a factory for the Order class. It is a plain class and should be instantiated freely. So yo u
scatter tons of new Order() instructions throughout your code. You don't see, though, that Order has some logical
dependency on, say, Customer .
At some point, a request for change hits you—in the next release, an order will be created only in association with a
customer. What can you do ?
If you only add a new constructor to the Order class that accepts a Customer object, you simply don't meet th e
requirement, because the old constructor is still there and only new code will follow the new pattern. If you drop o r
replace the old constructor, you have tons of new statements to fix that are scattered throughout the entire cod e
base.
If only you had defined a factory for the Order class, you would have met the new requirement without the same pain .
(By the way, domain-driven design methodology in fact suggests that you always use a factory for complex objects ,
such as aggregates.)
Changing a Member's Modifiers
When you design a class, you have to decide whether the class is public or internal and whether it is sealed o r
further inheritable. And then you decide whether methods are virtual or nonvirtual. Misusing the virtual and sealed
modifiers might take you along an ugly route .
In general, when you use the sealed and virtual modifiers you take on a not-so-small responsibility. In C#, by defaul t
each class is unsealed and each method on a class is nonvirtual. In Java, for example, things go differently fo r
methods, which are all virtual by default. Now what should you do with your .NET classes? Make them sealed, o r
go with the default option?
The answer is multifaceted—maintenance, extensibility, performance, and testability all might factor into you r
decision. We're mostly interested in maintenance and extensibility here, but we'll return to this point in Chapter 3
when we touch on design for testability and make some performance considerations .
From a design perspective, sealed classes are preferable. In fact, when a class is sealed from the beginning yo u
know it—and you create your code accordingly. If something happens later to justify inheritance of that class, yo u
can change it to unsealed without breaking changes and without compromising compatibility. Nearly the same can b e
said for virtual methods, and the visibility of classes and class members, which are always private by default .
The opposite doesn't work as smoothly. You often can't seal a class or mark a virtual method as nonvirtual withou t
potentially breaking some existing code. If you start with most-restrictive modifiers, you can always increase th e
visibility and other attributes later. But you can never tighten restrictions without facing the possibility of breakin g
existing dependencies. And these broken dependencies might be scattered everywhere in your code .
To contrast these statements, some considerations arise on the theme of testability. A nonsealed class and virtua l
methods make testing much easier. But the degree of ease mostly depends on the tool you use for testing. Fo r
example, TypeMock is a tool that doesn't suffer from these particular limitations .
It's hard to make a choice as far as the sealed and virtual keywords are concerned. And whatever choice you make i n
your context, it doesn't have to be a definitive choice that you blindly repeat throughout your code for each class an d
member. Make sure you know the testability and performance implications, make sure you know the goals and scop e
of your class, and then make a decision. And, to the extent that it's possible, make the right decision !
Requirements and Quality of Softwar e
The mission of the system is expressed through a set of requirements. These requirements ultimately drive th e
system's architecture.
In rather abstract terms, a requirement is a characteristic of the system that can either be functional o r
nonfunctional. A functional requirement refers to a behavior that the system must supply to fulfill a given scenario. A
nonfunctional requirement refers to an attribute of the system explicitly requested by stakeholders .
Are the definitions of functional and nonfunctional requirements something standard and broadly accepted? Actually ,
an international standard to formalize quality characteristics of software systems has existed since 1991 .
Examining the ISO/IEC 9126 Standar d
As a matter of fact, failure to acknowledge and adopt quality requirements is one of the most common cause s
that lead straight to the failure of software projects. ISO/IEC 9126 defines a general set of quality characteristic s
required in software products.
The standard identifies six different families of quality characteristics articulated in 21 subcharacteristics. The mai n
families are functionality, reliability, usability, efficiency, maintainability, and portability. Table 1-1 explains them i n
more detail and lists the main subcharacteristics associated with each .
Table 1-1. Families of Quality Characteristics According to ISO/IEC 912 6
Family Description
Functionality Indicates what the software does to meet expectations. It is based on requirements such a s
suitability, accuracy, security, interoperability, and compliance with standards an d
regulations.
Reliability Indicates the capability of the software to maintain a given level of performance when use d
under special conditions. It is based on requirements such as maturity, fault tolerance, an d
recoverability. Maturity is when the software doesn't experience interruptions in the case o f
internal software failures. Fault tolerance indicates the ability to control the failure an d
maintain a given level of behavior. Recoverability indicates the ability to recover after a
failure.
Usability Indicates the software's ability to be understood by, used by, and attractive to users. I t
dictates that the software be compliant with standards and regulations for usability .
Efficiency Indicates the ability to provide a given level of performance both in terms of appropriate an d
timely response and resource utilization .
Maintainability Indicates the software's ability to support modifications such as corrections, improvements ,
or adaptations. It is based on requirements such as testability, stability, ability to b e
analyzed, and ability to be changed .
Portability Indicates the software's ability to be ported from one platform to another and its capability t o
coexist with other software in a common environment and sharing common resources .
Subcharacteristics are of two types: external and internal. An external characteristic is user oriented and refers to a n
external view of the system. An internal characteristic is system oriented and refers to an internal view of the system .
External characteristics identify functional requirements; internal characteristics identify nonfunctional requirements .
As you can see, features such as security and testability are listed as requirements in the ISO standard. This mean s
that an official paper states that testability and security are an inherent part of the system and a measure of it s
quality. More importantly, testability and security should be planned for up front and appropriate supporting function s
developed.
Important
If you look at the ISO/IEC 9126 standard, you should definitely bury th e
practice of first building the system and then handing it to a team of network an d
security experts to make it run faster and more securely. You can't test quality i n
either. Like security, quality has to be designed in. You can't hope to test for an d
find all bugs, but you can plan for known failure conditions and use clean codin g
practices to prevent (or at least minimize) bugs in the field .
It's surprising that such a practice has been recommended, well, since 1991. T o
give you an idea of how old this standard is, consider that at the time it wa s
written both Windows 3.0 and Linux had just been introduced, and MS-DOS 5. 0
was the rage, running on blisteringly fast Intel i486 processors. It was anothe r
剩余485页未读,继续阅读
kisekitw
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C++多态实现机制详解:虚函数与早期绑定
- Java多线程与异常处理详解
- 校园导游系统:无向图实现最短路径探索
- SQL2005彻底删除指南:避免重装失败
- GTD时间管理法:提升效率与组织生活的关键
- Python进制转换全攻略:从10进制到16进制
- 商丘物流业区位优势探究:发展战略与机遇
- C语言实训:简单计算器程序设计
- Oracle SQL命令大全:用户管理、权限操作与查询
- Struts2配置详解与示例
- C#编程规范与最佳实践
- C语言面试常见问题解析
- 超声波测距技术详解:电路与程序设计
- 反激开关电源设计:UC3844与TL431优化稳压
- Cisco路由器配置全攻略
- SQLServer 2005 CTE递归教程:创建员工层级结构
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功