Thoughts on ActiveRecord, domain model, and iBatis

Source: Internet
Author: User

First, I want to explain that this is an article about pure stream of consciousness,

Where do you think about it. Bloggers with strong data structures and process logic control can skip this step ......

 

Thoughts on ActiveRecord, domain model, and iBatis

 

Recently I have read various domain-oriented debates. The ActiveRecord-based design pattern can indeed convert DAO (Data Access Object) objects and DTO (Data Transfer Object) the Object and DMO Service (Domain Model Service Object) are naturally merged into a subclass inherited from ActiveRecordBase.

 

For example, DMO object PersonBase {public string Name {get; set;} public int Age {get; set;} public string State {get; set ;}}

Then, the Person object added with [ActiveRecord (Table = "Persons")] becomes a DAO object inherited from ActiveRecordBase.

Then, with the [DataContract] annotation, it immediately becomes a DTO (Data Transfer Object) that can be transmitted by WCF (Windows Communication Foundation ). By now, this PersonBase object is just a prototype of a person. Has the attributes of some people, such as age, name, and status. However, at this time, he was still a baby. In addition to setting its attributes and persistently entering the database, he could not do anything.

Create a new Person Extension from PersonBase Extension Method: Cry and StopCry

Person: PersonBase, IPersonService

{

Public PersonBase Cry (PersonBase person = null)

{

If (person = null)

{

This. State = "Crying ";

}

{

Person. State = "Crying ";

}

This. Update (); // call the Update method inherited from ActiveRecord to Update the database.

Return this;

}

Public PersonBase StopCry (PersonBase person = null)

{

If (person = null)

{

This. State = "Normal ";

}

{

Person. State = "Normal ";

}

This. Update ();

Return this;

}

}

 

Then create the Person Interface

[ServiceContract]

Public interface IPersonService

{

[OperationContract]

PersonBase Cry (PersonBase person = null );

[OperationContract]

PersonBase StopCry (PersonBase person = null );

}

In this case, the Person class with the ability to act has two actions: Cry and StopCry. In this case, you can use WCF to publish this Person as a Web Service or other forms of WCF Service.

 

In this case, the client can also share the services provided by the Person class.

Create a Proxy object through the ChannelFactory in WCF. The extension object on the client is also Person, and the Person object is also inherited from the server's PersonBase, the Person class of this client also implements the IPersonService interface.

 

Person: PersonBase, IPersonService

{

Public PersonBase Cry (PersonBase person = null)

{

PersonBase personback = proxy. Cry (this)

This. State = personback. State;

Return personback;

}

Public PersonBase StopCry (PersonBase person = null)

{

PersonBase personback = proxy. Cry (this)

This. State = personback. State;

Return personback;

}

}

 

The Person class is converted from DAO to DTO to DMO Service.

The core principle is to minimize code duplication. Class reusability is added to prevent a project from simultaneously maintaining Data Access Object, Data Transfer Object, and a Rich Domain Model Object.

 

The Domain Object here is a rich DMO Object containing Domain Model Data and Domain Model Service.

No more anemia. In addition, it can be simply inherited and reconstructed. For example, in the above example, the client still creates a Person class that extends from the PersonBase POCO. This class also implements the IPersonService interface and has the Cry and Stop actions.

 

Only the Person on the server performs relevant behaviors through the operation class itself.

The client's Person is the Cry and StopCry behavior of the Person class on the proxy server provided by WCF, in addition, the Person class of the client itself needs to be passed to the Service of the server through this reference as a parameter for relevant processing, and then the processing result is returned to the client.

It may sound too easy. But it is easy to understand.

 

There are two different classes for the Person class on the server and the Person class on the client. Why can they be transferred on the server and the client?

The answer is in the PersonBase class. Both the Person class on the server side and the Person class on the client side inherit from the common basic class PersonBase.

When Person appears on the server as a Service, the DataContract parameter must be passed as the PersonBase class. Based on the principle that child classes can be granted to parent type references. Theoretically, it is feasible.

 

We can see the disadvantages of ActiveRecord In the DMO-Oriented Domain Model.

The audience may have to criticize me here. I have been talking about it for a long time. It's not the Domain-oriented Model of the Domain Model ~ I am confused.

 

First, let's talk about my understanding of the domain-Oriented Programming Model:

I think the Domain Model is like this. For example, for a sales software, for sales personnel. The sales field is concerned with the sales price, discount, sales quantity, and who the marketing personnel are. Sales commission and so on. For the incoming personnel, it only cares about the price of the incoming goods, the channel of the incoming goods, and the supplier. For finance, it only cares about the amount of sales this month, as well as the sales cost and profit.

However, in the database, there may be only two tables, one is the purchase table and the other is the sales table.

Financial locks focus on the profit by executing related SQL statements in the database for statistical accounting, such as the total sales volume of the month.

Because the data for the financial field does not actually exist in a separate financial table. Therefore, if ActiveRecord is used for financial statistics at this time, this Domain Model Object will have a problem. Which table should it map?

 

Because ActiveRecord is a secondary encapsulation Based on NHibernate, nhibcord originated from hibernate.

(PS: I have not studied Castle ActiveRecord in depth, but I have participated in the development of several hibernate-based projects. hibernate is very troublesome for Mapping custom SQL statements to Pojo, it even violates the core idea of hibernate)

 

At the same time, the lightweight SQL Mapping Object iBatis is doing well in this aspect.

It can map arbitrary SQL query statements to custom Pojo (. net is Poco ).

 

Therefore, it is very suitable for the development of the domain model of the invoicing software above. (By writing specific SQL statements, use select sum (price ** discount * quantity) as TotalMoney ..... such statements map the TotalMoney field obtained by a specific statement query to the public int TotalMoney {get; set;} attribute of the class AccountingSum.

You can even merge two SQL statements to complete a specific domain behavior at the same time.

Such as Sales behavior: First sentence, insert into Sales (ItemName, Price, Quantity) values (soap, 100, 1 );

In the second sentence, update Stock set Quantity = Quantity-1 where ItemName = soap;

This implicit SqlTransition is used to complete a specific domain behavior.

 

So I think the problem may be:

Both hibernate and ibatis are too stubborn.

 

A Table must be oriented. Bind a Table To an Object To death (at least from the default situation, we recommend that you use Table Mapping To Object)

On the other hand, there is no Table bound, but you need to write Select xxx, yyy, * from table where xxxx = yyyy

A large number of SQL statements are required to retrieve a specific Record from a table based on the Primary Key.

Flexibility is good, but it is a bit cool. It cannot be as accustomed to being bigger than the Convention as hibernate (ActiveRecord.

ActiveRecord (hibernate) limits the functionality of many database servers.

For the induction statistics of large volumes of data, SQL statements are optimized based on their internal computing advantages and related statements. It is more efficient than traversing data one by one using hibernate and then making statistics.

 

For example:

Decimal totalmoney = 0.00 M:

Foreach (GoodItem item in GoodItemQueryList)

{

Totalmoney + = item. Price * item. Discount * item. Quantiy;

}

And

SQL statement

Select sum (price * discount * quantity) from GoodItem where...

 

Although both of these methods can achieve the same functions, I can see the advantages of performance in a new company.

First of all, from the data volume between SqlClient and SqlServer, it is obvious that the first type will generate a large amount of data exchange between the database client and the server.

 

Therefore, here I like to indicate that.

Ibatis is good, hibernate is good.

However, if the two crossfires can be used, the fire will be quite powerful. (Now I think of my Shanghai Volks Wagen CrossPolo, very small and powerful !)

 

ActiveRecord (Hibernate) only uses the functions of the SQL Server, or most people who use Hibernate are influenced by their core ideas,

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.