How to build the software of low-coupling high cohesion under the framework of Struts+spring+hibernate

Source: Internet
Author: User

I often think about a problem, how can we design high-level, high-quality software come out. What is a high-level, high-quality software? It should be easy to maintain, easy to adapt to change, good reusability of a system. How do we do that? The answer is, of course, "low-coupling, cohesion." Low coupling is when the software is constructed, the various modules, functions, and classes are not overly dependent on the environment around it. Only in this way can our modules (functions, classes) be unaffected by changes around them, making them easy to maintain and adaptable to change. Because of this, it also makes it easier to reuse into other environments with similar functionality, and improves reusability. High cohesion the software in the various modules (functions, classes) can do their best and full cooperation, that is, for the software problem space requirements of the various functions, the system can be reasonably assigned to each module (function, Class) to co-complete, rather than one or a few slick, fit all super Class A person to complete. And for a module in the System (function, Class), has its own highly relevant responsibilities, that is, several tasks in this responsibility are highly correlated. Each module (function, Class) will never accomplish tasks unrelated to its own responsibilities.

So how to construct a low-coupling, high cohesion system can, one of the most popular framework structure of the struts+spring+hibernate for us to provide convenience. Using struts we can apply the MVC model to separate the page presentation from the business logic, so that the low coupling between the page presentation and the business logic is achieved. When we need to change our page, we only need to modify our page, without affecting our business logic, and as our business logic needs to change, we only need to modify our Java program, regardless of our page. Using spring we use the IOC (reverse control) to reduce the interdependence of the various classes in the business logic. If Class A calls Class B because it needs a function f, class A usually needs to refer to Class B, so Class A relies on class B, which means that class A cannot be used when Class B does not exist. Using IOC, Class A invokes only a class that implements the interface of function f, which may be Class B or another class C, as determined by the spring configuration file. In this way, Class A is no longer dependent on class B, and the degree of coupling decreases and reusability increases. Hibernate is the separation of our business logic from data persistence, that is, the operation of storing data to a database. In the business logic, we just need to put the data in the value object and then give it to hibernate, or get the value object from Hibernate. As for Oracle, MySQL, or SQL Server, I have nothing to do with the operation.

But what I'm saying is, even if we use the Struts+spring+hibernate framework to build our software, can we do "low-coupling, cohesion-poly"? I think this is far from enough! I think we often have the following questions to improve when using the struts+spring+hibernate framework.

Analysis and decision making
  

1. Do not use Hibernate or spring support for hibernate directly when writing DAO.
  Now, when we write DAO, it is common to directly inherit the spring-to-Hibernate wrapper class Hibernatedaosupport, and then use this class to provide such things as saveorupdate (), Saveorupdatecopy (), and find () and so on. In addition, hibernate classes, such as query, Session, type, are also used when implementing some of the more complex hibernate functions using the Excute () method. The problem with such direct use of the spring and hibernate classes is that your code will have to rely on a version of spring and hibernate. For example, now hibernate3 out, change quite big, in fact the most deadly is the package structure, HIBERNATE2 package structure is net.sf.hibernate.*, but Hibernate3 is org.hibernate.*. Similarly, spring to support Hibernate3, the package name is also changed to org.springframework.orm.hibernate3.*. If you're developing a new project now, it doesn't matter if it's a matter of upgrading a project. If you want to upgrade one of your projects from Hibernate2 to Hibernate3, you have to modify all references to Hibernate and Spring-hibernate in DAO. If your code appears to have methods and classes that hibernate2 incompatible with hibernate3, such as Saveorupdatecopy () (which is not in the Hibernate3), you will have to rewrite it. Then you may say, I will not upgrade like this. If your software life cycle has been for many years, hibernate upgrades to 4, upgrade to 5, you still use Hibernate2? If you develop a platform in this way, can you ask all software projects that use your platform to use only hibernate2? To put it further, I am now developing a product that will be thousands of customers in the future. After 1 or 2 years I need to upgrade, when my upgrade package has dozens of M, almost all the DAO has been changed all over again, such an upgrade is a reload. Perhaps someone would suggest another option, adding a base class between Hibernatedaosupport and DAO, This changes the org.springframework.orm.hibernate.support.HibernateDaoSupport in the base class to Org.springframework.orm.hibernate3.support.Hiber NateDaosupport, so that the following inherited DAO will not have to change. However, in the source code is a small change, but for the class, two different versions of Hibernatedaosupport its related properties and methods have a lot of changes, then the base class recompile, your inheriting class recompile No. Since it has been recompiled, all of your DAO will still be in the upgrade package when upgrading, the problem still exists.

The reason for this is that the DAO in our project relies on Hibernate and spring, because our use of them is inheritance, is a strong association, is a kind of dependence. We can solve this problem with just a little bit of tweaking, which is to use interfaces for decoupling without using direct inheritance. You can use the facade mode, first set up a basic class called Basicdao, from the name we can see, it is all the basic class of DAO, to implement all the DAO operations such as Save (), delete (), load (), query () and other methods, In addition to some basic methods, such as page-flipping queries, GetCount, parsing query conditions to form HQL statements are also implemented here, but do not use any methods and classes related to hibernate or spring. At the same time, Basicdao calls an interface called Daosupport, and the Daosupport interface is the primitive element that provides the basic method required for persistence. Then, I provide a variety of implementations for the Daosupport interface, such as HIBERNATE2 implementation daosupporthibernateimp, HIBERNATE3 implementation Daosupporthibernate3imp, as shown in the entire structure. Basicdao can use Hibernate or spring-provided methods, but not directly, but by invoking the Daosupport implementation class. However, Basicdao is the implementation class that we use, and we use the spring IOC to determine which implementation is used through the configuration file. At the same time, Basicdao does not use classes such as Springcontext to implement IOC, but rather by establishing the Setdaosupport () and Getdaosupport () methods, and then establishing references in the spring configuration file.

2. do not use spring and spring inheritance classes directly when writing an action

  I said earlier that DAO should be avoided referencing spring or hibernate and its inheriting classes. The same thing happens in action. Because the action is usually not included in spring management, the action often refers to a class called Springcontext (The inheriting class of spring's class Contextloaderservlet) when calling a bus through spring. Then use its Getbean () method. For such use, our action will depend on spring. We can also use a parent class called basicaction, and then use an interface to isolate spring. Since action is not normally included in spring management, we use a *.property configuration file to determine which implementation class the interface invokes. Another benefit of such a structure is that we can also improve the maintainability of the system by placing all actions such as write logs, user checks, and exception handling in the parent class basicaction.

3. when the bus needs to obtain data from other modules, do not go directly to the module's DAO

I give a simple example: I need to design a software review of the management software, the software is divided into the review organizer to make a review plan, the reviewers completed the review form by the Review Organizer Summary Review form, review organizer production review report. This is a very simple project, divided into three people to complete. But there was a problem when the project came to a close. To complete the review form, you need to obtain some data from the review plan, and the data for the review report is derived from the review form. The project team opened a meeting before starting the program, and everyone agreed on the data format and its rules for each part, and then began to work. However, several days after the project team to integrate the various modules found that the system simply can not run up, why? The design review plan found that all review plans should be managed according to the product number rather than the project number. As a result of this change, the completion of the Review form module in the list to be reviewed can not display anything; Similarly, the Design Review table found that in a review plan the review table and the reviewer is not a one-to-many relationship, but the relationship between the two tables, and thus modified the association of the table. Because of this, in the production of the review report will not be properly obtained the review table data. In fact, a software project is always changing throughout the process. What we need to do is not to suppress these changes, but to adapt the software structure to these changes, that is, to reduce the dependence (coupling) between the modules, and improve the cohesion.

With this example, when the review table needs to invoke the data of the review plan, you should not write a DAO to invoke the data of the review plan, but should be the interface to call the review plan, and this task to the review plan class to complete. When the review report needs to call the data of the review table, it should also call the interface of the review table, which is implemented by the review table. At the same time, this call should be to call the bus layer interface. Why is it? For example, one of the business logic in the review plan is that the review plan can only be produced after the review plan is published, so what is the published review program? Who should define this business logic? Of course, the judging plan. Where do you define it? It is, of course, a bus rather than a DAO, because DAO is only the persistence of data, and bus is the place to implement business logic. That being the case, if the judging table calls the DAO of the Review plan, the business logic of the published review plan must be included in the business logic of the review form. Let's assume that one day the business logic for the review plan has been changed (which in fact happens to you inadvertently), and the person writing the review plan will soon revise the business implementation of the review plan and pass the test. He did not know that the review table also contains such business logic, so the modified program will run to the review form when it is likely to error. Unfortunately, in real work, the same business logic may be contained in countless code that you might know, but you may not know. Such a structure is a poor structure that is not easy to maintain.

  

Summary: Alistair Cockburn, a software development expert adapting to change in terms of technology upgrades and demand changes, said in agile software development that software changes throughout the life cycle are happening all the time. I think that the software changes on the one hand is the technology update, today we use struts+spring+hibernate, tomorrow, we will use what? Because technology is changing too quickly, our system should not rely too much on a specific technology or framework to facilitate tomorrow's technology updates. At the same time, changes in demand from customers are another pressure that we must face. A classic statement describes a customer's change: "When I see it, my needs change." (I changed just when I saw it.) "In the past we used the requirement specification to suppress user changes, and now we find that this is not the case." Agile Software Development proposes many ways to respond to user changes, in which the establishment of a low-coupling high cohesion software structure is one of the methods. All objects in the system have their own clear responsibilities, and this responsibility should be few and highly relevant. Each object should only fulfill its own duties and give other tasks to others. As I mentioned earlier, the review table object only completes the operation related to the review table, and in the task it needs to complete, it needs to use the relevant functions of the review plan data to be submitted to the review plan object to complete, the review table just call. Such a structure requires developers to coordinate, communicate with each other, but also need someone to unified planning, standing in the overall design of the system. Through these, we can adapt to change, improve the design level

How to build the software of low-coupling high cohesion under the framework of Struts+spring+hibernate

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.