Thursday, September 26, 2019

Summary of All Data Source Patterns

Simple Active Record (No Repository ) == RDG++
Simple Data Mapper (No Repository) ==  TDG++

Respository Based Active Record = Simple Active Record++
Repository Based Data Mapper = Simple Data Mapper++

Respository (Active Record) = Simple Active Record++
Repository (Data Mapper) = Simple Data Mapper++


When we are using ADO.NET and writing our own DAL, we are not using any ORM.
We are dealing ourself with all dirty work of Data Access

Writing SQL,Connections, Resultset fetching n mapping, exceptions, messaging,
casting, transactions,updating the database schema and domain model ourself

ORMs try to abstract these things out and make our life easy

Linq like language for quering data.
No connection management
No Result set dealing and mapping to Domain Model
No exception handling
No messages to upper layers
No Data type casting
No Transation Mgmt, it is done by UOW and Change Tracker
Database schema and Domain is synched by Code First Migrations

Two Types of Data source Patterns

1. Row Based Patterns
a. Row Data Gateway (No Domain Logic, Only Persistence Logic, Seperate Class for Querying, No Useful Pattern even for CRUD and BREAD)
b. Active Record (Domain Logic, Persisteance Logic, No SOC, Data, Getter, Setters in same Class, Improvment over RDG, used most in CRUD or BREAD scenarios, it is improvment of a)

2. Table Based Patterns
a. Table Data Gateway (No Domain Logic, Only Persistence Logic, Good SOC, Takes Primitive Data Types, Return Connected ResultSets, Not Useful Pattern even for CRUD and BREAD)
b. Data Mapper Pattern (Domain Logic, persistence Logic, Good SOC, Takes Entities/Domianobj/DTO as input, Returns disconnected Entities/DomainObj/DTO, Improvment over TDG, used most in CRUD and Bread, it is an improvment over a)

Above discussion clearly say

Active Record == Improvment over the RDG
Data Mapper == Improvement over the TDG

Active Record == RDG++
Data Mapper ==  TDG++

Active Record is good for extermely simple CRUD Domains
Data Mapper is good for exetremely complex Domain Centric scenarios

Most ORM provide support for above 2 patterns, both B are best
Rest of the Two Patters are dumb both As are dumb

In ORMs I think we have two types of Implement of ARP and DM Patterns

Intially we have Non-Repository Based half cooked implemenation of B Patterns, these implemetations remove 50% fo the dirty Data Access Job
We still have to do the dirt work of SQL Queries, Transaction Management, Custom UOW Classes, Custom Repositories
Non Repostory based Active Record Pattern
Non Repository based Data Mapper Pattern

Lately we have Repository Based fully cooked implementations of B Patterns, these implementations remove 90% of the dirty Data Access Job,
It prominently the provide, In-memory Repositories, LINQ Querying, UOW, Change Tracker.
Repostory based Active Record Pattern
Repository based Data Mapper Pattern

Simple Active Record (No Repository ) == RDG++
Simple Data Mapper (No Repository) ==  TDG++

Respository Based Active Record = Simple Active Record++
Repository Based Data Mapper = Simple Data Mapper++

Respository (Active Record) = Simple Active Record++
Repository (Data Mapper) = Simple Data Mapper++

Saturday, February 9, 2019

Three Roles of DBContext and DBSet in ASP.NET MVC

Three Roles of DBContext and DBSet in ASP.NET MVC

DBContext and DB Set in asp.net mvc has 3 roles

1. They act as the Virtual DB in the application. It is the representation of DB in the application, Connection Strings is related to it. All tables and repositories are in this class. This class is the base to the DB Connectivity in the application. Whereever we need DB functionality we need this class.

2. This class is the base to the Code First Migrations. This class hold the Entity Configurations. This class hold the Domain Model elements those we need to represent in the DB. This class glue the Domain Model and the DB Schema. Code First Migrations are done in the Context of DB Set represented in this class. All Entity Configurations/Fluent APIs are related to this class. Seed method is related to the Configuration class in Migration folder.

3. This class is central to the UOW/Repository in the ASP.NET MVC, DBContext is EF UOW, and DB Set is EF Repository using both in the Controller or Services does not yeild the benifits of UOW/Repo. We need to have Application Sepecific UOW and Entity specific Repo, to have the full benifits of UOW/Repo. Application specific UOW and Entity specific Repo are defined on the top of EF-UOW and Repo.

Application Specific UOW Class & Interfaces Samples



namespace CleanArchitecture.Application.Interfaces
{
    public interface IDatabaseService
    {
        IDbSet<Customer> Customers { get; set; }

        IDbSet<Employee> Employees { get; set; }
       
        IDbSet<Product> Products { get; set; }
       
        IDbSet<Sale> Sales { get; set; }

        void Save();
    }
}

Friday, February 8, 2019

How to implement UOW and Repository in OCH Architecture

EF provide UOW (DbConext) and Repositories (DbSet) but using them directly in
Controllers or Services is not required. Doing so reuslts in all disadvanges of poorly
architectured code.
We need to have Wrappers around EF UOW (DbConext) and Repositories (DbSet)
We put interfaces on top of these wrappers IUnitOfWork and IRepositories
Services and Controllers use these Interfaces to do persistence
All these interfaces are defined inside the Service or Controller layer
DI/IOC is used to intect depedencies to controllers or Services
Only then we get benifits of Good Arch

Why Service layer in Clean Architecture is a burden

Why Service layer in Clean or Onion or Hexagonal Architecture is a burden

Mosh is no OK with OCH architecture in defintion.
Overhead of Service Layer, if there is not complex application loigc and feature slice is very thin
Little bit application logic or orchestration of calling Domain Logic will go to Repositories or Controllers
Controller will know about the Domain Classes I think.
Mosh Arch == OCH Arch - Service Layer
No Physical Layers Projects, it increases complexity of Code base
Just Logical Layers in Projects, it increases understability.
Layers violatins are detected by Code Reviews
In case of Multiple Clients, we expose the Web API Controllers to expose the functionality,
No need of App. Services for exposing App Functionalitiy to Multiple Clients
Two Layers of Indrections make the Vertical Feature Slice complex, to understand, develop and maintain
Two Phases of Data Mappings make the Vertical Feature Slice complex, to understand, develop and maintain
We should use the Minified-Mosh-Version of OCH architecture.
Only add the services if the feature is fat and need orchestration
If the feature is flat CRUD Operation, do not go for that.
If the feature is fat, we need big Request Processing Pipeline, add componets in the pipeline
If the feature is flat CRUD, then Controller talking to Enitty Repository and Domain objects having little logic inside them is ok, little application logic will live inside the Controller or Repository. It is OK
Extension Methods on DbSet is the replacement of EntityRepsitories
TDD is the solution of spghetti often broken code. We still have to change things at many places, hampers productivity, understandability, hampers teamwork, More Merge Conflicts, Complex deployment, recompilation, re deployment,


1. Services Classes Command and Query Classes
2. Interfaces for Service Classes
3. Request Repose Models for Data Containers (No Interfaces required)
4. Seperate Testing Classes for Services
5. DI Classes, One extra layer of Indirection, to inject Repositories to Services
6. Mapping Code, Extra mapping code that map Domain obj to Request Response Model
7. Managing References for different projects, external referecnes, internel references

Where and When to Apply DDD

Problems is DDD community has come with elegant solutions for extremely complex business domains
When they come and share those solutions, they do not shared the context or very naively share the context
They describe this as extension of traditional 3 level arch and everybody start following them blindly with knwoing about the context
One should study his app context, one should study the solution business context and take that solution if the context is same
By the large 90% EAs are CRUD having little or not business or application logic
Remaining 10% complex business EA are 80% CRUD.
We take the Areoplance Structure and start fitting Auto Bike components inside it. Both are correct in isolation but their combination is wrong.
Auto Bike built with Aeroplance Structure result in extremely complex Auto Bike

Dependency Inversion Principle by Mosh Hamedani

Ist part of DIP
High Level Module ==> Interface/Contract/Abstraction ==> Low Level Module/Details
HLM should not depend upon LLM, both should depend upon abstraction
There should exist an interface between HLM/Layers and LLM/Layers
These Interfaces are defined inside the HLM layer.
If the Contract remain the same, High level module will be not effected.
If the Contract is simple and clean and thoughtful, predictive, chances are it will not change

2nd part of DIP
High Level Module ==> Interface/Contract/Abstraction <== Low Level Module/Details
Abstractions should not depend upon details, Details should depend upon Abstractions
Interface should be pure and generic, they should not have to leaky
Interface should be defined interms of only Interfaces.
Interface Methods should not use the Types with in LLM
All these interfaces are defined inside the HLM
If layers. LLM layer include the reference of HLM layer.
Arrows show the Dependency Flow not the Control Flow a runtime.

Benifits of OCH Arch for EA

Seperation of Concerns those change at different rate and due to different reasons. LCHC,  Arch should forces you to put things in right place
Abstraction,Encapsulation,Data hiding, Put a limit to the Details like ORM, CCCs libs, Infrastructure. By these wrappers and interfaces, only application required functionality is provided back to application, no more.
Vertical and Horizontal Understandability of code, prevent Complexity, BBOM, Tangled Sepghetti code, Conceptual Integrity,
Productivity, No Technical Debt, Design Statmina Hypothsis, Small Scope of Change
Changeability, Agility, IID, CI, CD,
Testability/TDD Benits of Testing/TDD
Better division of work among team memebers having different areas of experties. No dead locks.Independent Development of Assemblies, Components, Merge Conflict Issues with Team members
Deploybility, Independent Physical Deployment of Assemblies, Components, No recompilation and deployment of un effected parts,Small Scope of Change
Scalability, Scale Out the Applications Components easilty
Replaceability, Plugins, DB, App. Framework, UI Framework, ORM, CCCs libs, Infrastructure libs, Future Proofing, Growth Path,
Resuability more at Arch and Design Level, bit at Code level. Minimize duplication of code

Why DBSet and DBContext are not enough for Repository and UOW

Why DBSet and DBContext are not enough for Repository and UOW

DBSet and DBContext are the half of the story. They are completed by Entity Specific Repositories and Application or sub application specific UOW.

Only by having Entity specify Repo classes we can reap the benefits of Repository Pattern.

I am not sure application specific UOW is good or not. see mosh lectures and mathew rinzee Codebase.


EF provide UOW (DbConext) and Repositories (DbSet) but using them directly in
Controllers or Services is not required. Doing so reuslts in all disadvanges of poorly
architectured code.
We need to have Wrappers around EF UOW (DbConext) and Repositories (DbSet)
We put interfaces on top of these wrappers IUnitOfWork and IRepositories
Services and Controllers use these Interfaces to do persistence
All these interfaces are defined inside the Service or Controller layer
DI/IOC is used to intect depedencies to controllers or Services
Only then we get benifits of Good Arch

Friday, December 28, 2018

Domain Events : Why Use Events ? Event and Delegates.

Events are used to decouple the Caller from the Methods Calls.

Events are used to replace Method Calls.


Events encapsulate the Method Calls, along with Sender, Method Name and Data Passed to Method.


Events are used to decouple the important Domain Event and its Reaction.


Events are used to decouple the important occurrence in domain to the reaction code that should have to be executed against it.


Events are used to decouple Domain Action from Domain Reaction.

We decouple because the Domain Reaction/Business Logic could change over the time. For example, different Discount Rates, Different Promotions, Different Formals for Price Calculations.



Event is the Collection of EH-Methods. Delegates are used to define Events and tell about the signature of all EH-Methods.


Event has 6 steps related to them


1. Defining the Event Argument Class that encapsulate the Method Call. As told, Event is the O.O Representation of a Method Call. Methods take arguments, so the Event also takes argument. This class encapsulates the Domain Objects needed by Event Handlers to process the reactive Business Logic. It encapsulate the Data that we want to provide to the Subscribers to process the reactive Business Logic or Domain Logic. What is needed by the Event Handler is encapsulated inside the Event Arguments Class.


2. Defining the Delegates in the Publisher as public member. This defines the Method Signature of Event Handlers of all Subscribers those will listen to this event. All Event Handlers of an Event will have same signature and definition of this Method Signature is defined inside the publisher as Delegate. DELEGATE is used to tell EVENT about the METHOD SIGNATURE of all EVENT HANDLERS. Delegates are used in the definition of Events. Event is the Collection of EH-Methods. Delegates are used to define Events and tell about the signature of all EH-Methods.


3. Defining the Event instance variable inside the Publisher. This definition include the Delegate Definition inside it. This Event Variable is used to store the List of Event Handlers of interested Subscribers. Event is the Array of Method/Event Handlers Pointers such that Event Handlers have same signature. It holds the reference of all Methods/EH of different Subscribers. This is Array of Subscriber's Methods not the Array of Subscribers. So, Delegates are used in the definition of Events. Event is the Collection of EH-Methods. Delegates are used to define Events and tell about the signature of all EH-Methods.


4. Raising an Event inside the Publisher. This is a magic Method Call. Raising an event means, we calling the EH Methods of all Subscribers when something interesting happens inside Publisher. One Method Call results in Several Method Call. 5 subscribers 5 EH method calls. This is like iterating over the list of subscribers and calling their Event-Handlers. If there are Subscribers then raise the Event if not then Event is not Raised.


5. Definition of the Event Handlers. It is defined inside the Subscribers. Event Handler could be inside the Container or inside any Object inside the Container. So Subscriber could be container or it could be separate Object Living inside the Container.


6. Binding the Publisher's Events and Subscriber's EH Methods.  This is done either inside the Subscriber or in Container. Either we bind Event to Container's EH-Method or it could be bind to any other Container's Object's EH-Methods.

==============================

delegate is a way of telling C# which method to call when an event is triggered. For example, if you click a Button on a form, the program would call a specific method. It is this pointer that is a delegate. Delegates are good, as you can notify several methods that an event has occurred, if you wish so.

An event is a notification by the .NET framework that an action has occurred. Each event contains information about the specific event, e.g., a mouse click would say which mouse button was clicked where on the form.

Delegates[edit]

Delegates form the basis of event handling in C#. They are a construct for abstracting and creating objects that reference methods and can be used to call those methods. A delegate declaration specifies a particular method signature. References to one or more methods can be added to a delegate instance. The delegate instance can then be "called", which effectively calls all the methods that have been added to the delegate instance. A simple example:

using System;
delegate void Procedure();

class DelegateDemo
{
    public static void Method1()
    {
        Console.WriteLine("Method 1");
    }

    public static void Method2()
    {
        Console.WriteLine("Method 2");
    }

    public void Method3()
    {
        Console.WriteLine("Method 3");
    }

    static void Main()
    {
        Procedure someProcs = null;

        someProcs += new Procedure(DelegateDemo.Method1);
        someProcs += new Procedure(Method2);  // Example with omitted class name

        DelegateDemo demo = new DelegateDemo();

        someProcs += new Procedure(demo.Method3);
        someProcs();
    }
}



Methods that have been added to a delegate instance can be removed with the -= operator:
someProcs -= new Procedure(DelegateDemo.Method1);
In C# 2.0, adding or removing a method reference to a delegate instance can be shortened as follows:
someProcs += DelegateDemo.Method1;
someProcs -= DelegateDemo.Method1;
Invoking a delegate instance that presently contains no method references results in a NullReferenceException.
Note that, if a delegate declaration specifies a return type and multiple methods are added to a delegate instance, an invocation of the delegate instance returns the return value of the last method referenced. The return values of the other methods cannot be retrieved (unless explicitly stored somewhere in addition to being returned).

Events[edit]

An event is a special kind of delegate that facilitates event-driven programming. Events are class members that cannot be called outside of the class regardless of its access specifier. So, for example, an event declared to be public would allow other classes the use of += and -= on the event, but firing the event (i.e. invoking the delegate) is only allowed in the class containing the event. A simple example:
delegate void ButtonClickedHandler();
class Button
{
    public event ButtonClickedHandler ButtonClicked;
    ButtonClicked += ()=>{Console.WriteLine("click simulation !")};    
    public void SimulateClick()
    {
        if (ButtonClicked != null)
        {
            ButtonClicked();
        }
    }
    ...
}
A method in another class can then subscribe to the event by adding one of its methods to the event delegate:
Button b = new Button();
b.ButtonClicked += ButtonClickHandler();
Even though the event is declared public, it cannot be directly fired anywhere except in the class containing it.

BASIS FOR COMPARISONDELEGATESEVENTS
BasicA delegate holds the reference of a method.The event is an over-layered abstraction provided to the delegates.
Syntaxdelegate return_type delegate_name(parameter_list);event event_delegate event_name;
KeywordA delegate is declared using a keyword "delegate."An Event is declared using a keyword "event".
DeclarationA delegate is declared outside any class.An event is declared inside a class.
InvokeTo invoke a method it has to be referred to the delegate.To invoke a method it has to be assigned to the event.
Covariance and ContravarianceThey provide flexibility to the delegates.No such concept.
Event AccessorNo such concept.Manages the list of the event handlers.
DependencyDelegates are independent of events.The event can not be created without delegates.







Thursday, December 27, 2018

Main Theme of CQRS

CQRS main theme is against the Layers. 

Layers forces use to think applications in such a way that our Classes become BBOM and handling many concerns a one time. Read and Write.

Re usability of Classes/Data holding Data Structure/methods force us to have Classes those are BBOM and handling too many concerns at one time. Making Classes reusable and convert all the scenarios

Table/View oriented classes make them BBOM because we are forced to put all logic related to a table inside the Table Class. Results in a Table Class that is BBOM. 

These Layers, Resuability, DB Schema oriented Classes forces us to have BBOM Classes. This thing hides the Vertical Slices in the Application.

Instead, CQRS forces us to think Application as vertical slices

Things are much more Vertical Abstraction Oriented. or View or feature orinted.

We design applications by Vertical Features and We do not try to reuse Classes, Views, ViewModel, Controllers, RequestModel, ResponseModel, Command AS, Queries AS, Repositories, Factories, Domain Events, Domain Services and all Data Structures in View, AS and Data Layer. are specific to a feature. All these Classes are encapsulated inside the Folders for the Feature and they are specific to that Feature. Only Entities and VO and Domain Events seems outside this Vertical Slices. In the Domain Model things are generic and shared across the Vertical Slices.

In

Wednesday, December 26, 2018

Layered Architecture

Software Development Fundamentals, Part 2: Layered Architecture

This is part of a series of introductory guidelines for software development. It’s a continuation of the previous post about Dependency Injection.
One of the primary reasons to adopt Dependency Injection is that it is impossible to achieve a good layered architecture without it. Many developers argue that IoC container is only beneficial if you are doing test-driven-development. I disagree. I can’t quite think of how else you can build any layered architecture at all without IoC.
First, let’s take a moment to define layered architecture. There is a common misconception about layered architecture, which is largely contributed by misleading diagrams in most textbooks and articles. This is how layered architecture often described in textbooks.
image
I think that’s rather deceptive. Unfortunately, developers often take this diagram too literally. Each layer depends on the layers below it. Presentation layer depends on business-layer, and then both depend on data-access layer.
There is a huge flaw in that diagram. Data-access layer should be at the outmost part of application. Business layer should be at the core! But in this diagram, Data-access layer is becoming the core foundation of the whole application structure. It is becoming the critical layer. Any change on data-access layer will affect all other layers of the application.
Firstly, this architecture shows an incongruity. Data-access layer, in reality, can never be implemented without dependencies to business detail. E.g. DbUserRepository needs to depend on User. So what often happens is developers start introducing a circular dependency between Business layer and DataAccess layer. When circular dependency happens between layers, it’s no longer a layered architecture. The linearity is broken.
Secondly, which is more important, this architecture tightly couples the whole application to infrastructure layer. Databases, Web-service, configurations, they are all infrastructure. This structure could not stand without the infrastructure. So in this approach, developers build the system starting from writing the infrastructure plumbing first (e.g. designing database-tables, drawing ERD diagram, environment configuration), then followed by writing the business code to fill the gaps left by the infrastructural bits and pieces.
It’s a bit upside-down and not quite the best approach. If a business-layer couples itself with infrastructure concerns, it’s doing way too much. Business layer should know close to nothing about infrastructure. It should be in the very core of the system. Infrastructure is only a plumbing to support the business-layer, not the other way around. Infrastructure details are most likely to change very frequently, so we definitely do not want to be tightly coupled to it.
Business layer is an area where you have the real meat of your application. You want it to be clean of any infrastructure concerns. Development effort starts from designing your domain-code, not data-access. You want to be able to just write the business code right away without setting up, or even thinking about, the necessary plumbings. One of the guideline in previous post is that we want classes within business layer to be POCO. All classes in business layer should describe purely domain logic WITHOUT having any reference to infrastructure classes like data-access, UI, or configuration. Once we have all domain layer established, then we can start implementing infrastructure plumbing to support it. We get all our domain models baked properly first, before we start thinking about designing the database tables to persist them.
So this is a more accurate picture for layered architecture.
image
Infrastructure sits at the top of the structure. Domain layer is now the core layer of the application. It doesn’t have any dependency to any other layer. From code perspective, Domain project does not have any reference to any other project, or any persistence library. Databases, just like other infrastructure (UI, web-services), are external to the application, not the centre.
Thus, there is no such thing as “database application”. The application might use database as its storage, but simply because we have some external infrastructure code in the neighbourhood implementing the interfaces. The application itself is fully decoupled from database, file-system, etc. This is the primary premise behind layered architecture.
Alistair Cockburn formalizes this concept as Hexagonal Architecture, so does Jeffrey Palermo as Onion Architecture, but they truly are merely formalized vocabularies to refer to the old well-known layered architecture wisdom.

Onion Architecture

To describe the concept, let’s switch the diagrams into onion-rings. Jeffrey Palermo describes bad layering architecture as follows:
image
In onion diagram, all couplings are toward the centre. The fundamental rule is that all code can only depend on layers more central, never on the layers further out from the core. This way, you can completely tear out and replace the skin of the onion without affecting the core. But you can’t easily take away the core without breaking all outer layers.
In the diagram above, the infrastructure sits in the core of the onion. It becomes an unreplaceable part of the system. The structure cannot stand without infrastructure layer in the core, and the business layer is doing too much by embracing the infrastructure.
This is the better architecture model:
image
UI and infrastructure sits right at the edge skin of the application. They are replaceable parts of the system. You can take the infrastructure layer completely and the entire structure stays intact.

Implementation

Take a look at the diagram again.
image
If you follow the previous post, we were building “resend PIN to email” functionality. AuthenticationService is in the domain layer at the core of application, and it does not have knowledge about SMTP client or database (or even where User information is stored). Notice that DbUserRepository and SmtpService are in outmost layer of the application, and they depend downward on the interfaces in the core (IUserRepository, IEmailService) and can implement them. Dependency Injection is the key.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AuthenticationService: IAuthenticationService
{
    IUserRepository userRepository;
    ICommunicationService communicationService;
 
    public UserAuthenticationService(IUserRepository userRepository, ICommunicationService communicationService)
    {
        this.userRepository = userRepository;
        this.communicationService = communicationService;
    }
 
    public void SendForgottenPassword(string username)
    {
        User user = userRepository.GetUser(username);
        if(user != null)
            communicationService.SendEmail(user.EmailAddress, String.Format("Your PIN is {0}", user.PIN));
    }
}
At runtime, IoC container will resolve the infrastructure classes that implement the service interfaces (IUserRepository, ICommunicationService) and pass them into UserAuthenticationService constructor.

Project Structure

My typical project structure looks like this in Visual Studio:
image
I separate each layer into its own project. One of the benefits is that it physically enforces linear dependencies. Each layer can only depend on the layer below it. If a developer introduces a circular dependency between Domain layer and Data-Access, Visual Studio (or Java’s Eclipse) won’t even compile. Here is how these projects work together within the architecture:
image
Every component depends only to the components in the layer below it. As you can see, the only project that has reference to System.Data and NHibernate library is Sheep.Infrastructure.Data. Likewise, the only project with System.Web.Servicesreference is Sheep.Infrastructure.BackEnds. And none of those infrastructure projects is referenced by any other part of the application (and this is enforced by Visual Studio). Therefore, they can be totally taken away and replaced without affecting the application core. On the flip side, the whole infrastructure layer is tightly coupled on the core layer.
Domain layer is POCO. It does not depend on any other project, and it does not contain any reference to any dll for particular technology. Not even to IoC framework. It contains just pure business logic code. In order to be executed, this assembly has to be hosted either within a system that can provide infrastructure implementation, or within test system that provides mock dependencies. Hence notice that we have 2 versions of top-level skins in the structure: Infrastructure and Test.
So what’s the benefit?
  1. Domain layer is now clean of infrastructure concern. Developers actually write business code in human readable language, not a messy pile of SQL statements/NHibernate, socket programming, XML document, or other alien languages
  2. You can write domain code straight from the start without system consideration or waiting for infrastructure implementation. I.e. you don’t need a database at early stage of development, which is invaluable because you eliminate the overhead of keeping your database schemas in sync with domain models that are still shaky and keep changing every few minutes.
  3. The application core can be deployed for any client or any infrastructure, as long as they can provide the implementation for the service interfaces required by the domain layer.
Basically, it all describes Single Responsibility Principle (each class should only have 1 reason to change). In the classic diagram, being tightly coupled to data-access layer, domain layer needs to change because of some changes in infrastructure details. Whereas in layered architecture, you can completely tear apart the infrastructure layer at the skin, and replace with arbritary implementation without even laying a finger on any domain class at the core. Thus there is only 1 reason the classes in domain layer need to change: when the business logic changes.
Having said that, this architecture is not necessarily the best approach for all kind of applications. For simple form-over-data applications, Active-Record approach is probably better. It couples the whole application directly to data-access concerns, but it allows a rapid pace of data-driven development. However, for most non-trivial business applications, loose coupling is a very crucial aspect of maintainability.
This whole post is actually an introduction to our next dicussion about Domain Driven Design in some later post.
To be continued in part 3, Object Relational Mapping