2. Agenda Introduction Enterprise Architecture and Design What is Bad Design? Good Design Principles for Enterprise Development Single Responsibility Principle The Open Close Principle Dependency Inversion Principle Demo: Applying Principles
3. Introduction Why we are here? From Project development to Product development As we build framework on these principles We want you to start taking care of them To achieve our vision we need to strive for it
4. Enterprise Architecture “Enterprise Architecture is typically used to describe an organization-wide framework for portraying and incorporating the business processes, information flows, systems, applications, data and infrastructure to effectively and efficiently support the organization needs.”
5. Enterprise ArchitectureDeveloper’s point of view Defining a process, framework and set of patterns to design, develop, build and maintain all the software that an organization Unified development platform for creating all elements of software at all levels of design The reusable elements can then be used to geed or drive other applications with similar need Defining solid foundation of code and practices that eventually facilitate interoperability in the heterogeneous software environment
6. Enterprise Development Patterns and practices adopted by programmers endeavoring to implement enterprise architecture They address five key areas: Reliability Flexibility Separations of Concerns Reusability Maintainability
7. Hold on hold… One might think that simple, non-enterprise code that delivers a particular feature is identical in value to enterprise code that delivers precisely the same feature? While enterprise sample might look a bit more complex (only at first), the resulting class or module ultimately provides more reliability or is more maintainable
8. Bad design is... Hard to change! A single change break lots of other code Rigid Fragile Can’t be ‘extended’ Immobile
9. Good Design Principles Enterprise development requires a change in methodologies We are going to look some good design principles now By core, we take care of two things Modularity Loosely Coupled Classes
10. The Single Responsibility Principle "A responsibility is a reason to change, a class or module should have one, and only one, reason to change."
11. The Single Responsibility Principle “There should never be more than one reason for a class to change.” Dijkstra’sSoC: Separation of Concerns Applies on every level of code
14. The Open Closed Principle “Software Entities (Classes, Modules, Functions, etc.) should be open for extension, but closed for modification”
15. The Open Closed Principle Modules that conform to the open-closed principle have two primary attributes Open For Extension behavior of the module can be extended Closed for Modification The source code of such a module is inviolate The normal way to extend the behavior of a module is to make changes to that module. How can these two opposing attributes be resolved?
16. The Open Closed Principle Abstraction is the key to achieve it Server Client Closed Client
17. The Open Closed Principle Abstract Server Client Server Open Client
18. Liskov Substitution Principle “Functions that reference a base class must be able to use objects of derived classes without knowing it."
19. Dependency Inversion Principle “High level modules should not depend upon low level modules. Both should depend upon abstractions. “ “Abstractions should not depend upon details. Details should depend upon abstractions.”
20. BusinessParty Validator Introduce stability with abstraction High Level (Less Stable) BusinessParty Source BusinessParty Validator Trade DB Low Level (More Stable)
24. Reference and Further Learning Professional Enterprise .NET Jon Arking and Scott Millett Combating Software Entropies with Design Principles and Patterns at Tech-Ed ME HammadRajjoub ObjectMentor.com http://www.objectmentor.com/resources/articles/ Practices and Patterns on MSDN http://msdn.microsoft.com/en-us/practices/default.aspx
Notas do Editor
The operative phrase here is all of the software. It includes reusable tools for building client applications, websites, databases, office applications, business automation tools, scripts, and just about anything else that a company may use to get things done.
Enterprise development commonly refers to the patterns and practices adopted by programmers endeavoring to implement enterprise architecture.It is the employment of certain approaches and methodologies that aim to achieve many of the root goals inherent to a successful enterprise system.Reliability: Most would agree that designing systems that are reliable is a must. Yet coding for reliability is a departure from business as usual. This is especially true in the rapid application development community. Many enterprise enthusiasts exchange the term reliability for testability, since most modern enterprise coding patterns aim to facilitate unit testing. Writing code that can be well tested means changing the way that a system’s functionality is modularized.Flexibility: Requirements can change. As a result, so must the software that supports them. If the code that you write prevents an application or system from being extensible, we would say it lacks flexibility. A flexible system allows for the changing of core features without violating unrelated services or attributes. FLEXIBILITY IS DIFFERENT FROM INTEROPERABILITY. Separation of Concerns: Separation of concerns is simply the process of breaking a system or application down into distinct functional layers with limited overlapping of functionality. Like flexibility, separation of concerns address the ability to modularize code and make it more pliable, with the added benefit of logical division.Reusability: Sharing features and services is tantamount to good enterprise design. As code is broken down and separated into logical pieces, these pieces should be designed to provide a distinct feature or satisfy a particular requirement of other system that invoke it. In other words, classes at any one logical level should be reusable by other classes in the same logical level.Maintainability: Maintainability refers to the capacity of a system to be altered or modified. The term maintainability actually means the ease with which a software product can be modified in order to support:StabilityAnalyzabilityChangeability Testability
Yet this shortsighted evaluation fails to address the greater needs of the system, namely core enterprise concepts.
How many times have you come across the code that you can qualify as a ‘bad design’? Or atlease and most commonly would have said, That’s not the way I would have done it.Before we move on. Lets agree on what's a bad design? Ok it’s a bit difficult to be exact about the metrics of bad design in software. But lets agree on some common aspects of bad design.A piece of software that fulfills its requirements and yet exhibits any or all of the following threetraits has a bad design.1. It is hard to change because every change affects too many other parts of the system.(Rigidity)2. When you make a change, unexpected parts of the system break. (Fragility)3. It is hard to reuse in another application because it cannot be disentangled fromthe current application. (Immobility)Moreover, it would be difficult to demonstrate that a piece of software that exhibits none of those traits, i.e. it is flexible, robust, and reusable, and that also fulfills all its requirements, has a bad design. Thus, we can use these three traits as a way to unambiguouslydecide if a design is “good” or “bad”.Code that’s hard to change is bad… Rigid code is bad!Code that has lots of ripple effects.. A single change break lots of other code. Fragile code is bad!Code that cant be re-used… Code that cant be ‘extended’ is bad.. Immobile
Along with new set of development tools and design patterns, enterprise development requires a change in methodologies.
If a class has more then one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class’ ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.
What is responsibility? … It is a reason for change.If you can think of more than one motive for changing a class, then that class has more than one responsibility.The term separation of concerns was probably coined by Edsger W. Dijkstra in his 1974 paper "On the role of scientific thought"[1].Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one's subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained --on the contrary!-- by tackling these various aspects simultaneously. It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of. This is what I mean by "focusing one's attention upon some aspect": it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect's point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.
Example do demonstrate role based interfaces IVE examples
Classes should have a single responsibility or jobDevelopers should have that job in mind when they work on a classA developer should easily be able to write a block comment at the top of a class identifying its job.That comment should not have the word AND in it.As architects and leads we should be able to ask this question.. Whats the job of this class? a developer should always have this job in mind use intuitive and simple names remember! no conjunctions (ANDS)
When a single change to a program results in a cascade of changes to dependent modules, that program exhibits the undesirable attributes that we have come to associate with “bad” design. The program becomes fragile, rigid, unpredictable and unreusable. The open closed principle attacks this in a very straightforward way. It says that you should design modules that never change. When requirements change, you extend the behavior of suchmodules by adding new code, not by changing old code that already works.
When a single change to a program results in a cascade of changes to dependent modules, that program exhibits the undesirable attributes that we have come to associate with “bad” design. The program becomes fragile, rigid, unpredictable and unreusable. The open closed principle attacks this in a very straightforward way. It says that you should design modules that never change. When requirements change, you extend the behavior of suchmodules by adding new code, not by changing old code that already works.1. They are “Open For Extension”.This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications.2. They are “Closed for Modification”.The source code of such a module is inviolate. No one is allowed to make sourcecode changes to it.It would seem that these two attributes are at odds with each other. The normal way to extend the behavior of a module is to make changes to that module. A module that cannot be changed is normally thought to have a fixed behavior. How can these two opposing attributes be resolved?
The abstractions are abstract base classes, and the unbounded group of possible behaviors is represented by all the possible derivative classes.It is possible for a module to manipulate an abstraction. Such a module can be closed for modification since it depends upon anabstraction that is fixed. Yet the behavior of that module can be extended by creating new derivatives of the abstraction.Figure 1 shows a simple design that does not conform to the open-closed principle.Both the Client and Server classes are concrete. There is no guarantee that the member functions of the Server class are virtual. The Client class uses the Server class.If we wish for a Client object to use a different server object, then the Client class must be changed to name the new server class.
Figure 2 shows the corresponding design that conforms to the open-closed principle.In this case, the AbstractServer class is an abstract class with pure-virtual member functions. the Client class uses this abstraction. However objects of the Client class will be using objects of the derivative Server class. If we want Client objects to use a different server class, then a new derivative of the AbstractServer class can be created. The Client class can remain unchanged.
The importance of this principle becomes obvious when you consider the consequences of violating it. If there is a function which does not conform to the LSP, then that function uses a pointer or reference to a base class, but must know about all the derivatives of that base class. Such a function violates the Open-Closed principle because it must be modified whenever a new derivative of the base class is created.There is a strong relationship between the LSP and the concept of Design by Contract as expounded by Bertrand Meyer2.