IOC (reproduced)

Source: Internet
Author: User
1. Dependency

Dependency is associated. If dependency is used locally, dependency is dependent on it. A system cannot completely avoid dependency. If a class or module does not use it in the project, congratulations, you can remove it from the project or exclude it, because none of them will depend on it. The following is a simple example:

/// <Summary> /// the user plays a media file /// </Summary> public class operationmain {

Public void playmedia () {mediafile _ mtype = new mediafile (); player _ player = new player (); _ player. play (_ mtype) ;}//< summary> /// player //</Summary> public class player {public void play (mediafile file) {console. writeline (file. filepath) ;}/// <summary> // media file /// </Summary> public class mediafile {Public String filepath {Get; Set ;}}

The above is a simple example of a user playing a file with a player. The user operation is the playmedia method in the operationmain class. Open a player and select a file for playing. First, let's look at the dependency between them. We can simply find three dependencies.

  1. Player depends on mediafile
  2. Operationmain depends on player
  3. Operationmain depends on mediafile
2. Dependency inversion

The demand has increased. We need to abstract different players and play different files to reduce coupling.

Coupling is the dependency. If the dependency is complex, it is difficult to maintain the dependency. The less the dependency, the lower the coupling relationship, and the more stable the system. Therefore, we need to reduce the dependency.

Fortunately, Master Robert Martin proposed the object-oriented design principle-Dependency inversion principle:

  • A. Upper-layer modules should not depend on lower-layer modules. They both depend on an abstraction.
  • B. abstraction cannot depend on visualization, while it depends on abstraction.

Understanding:. the upper layer is the user, and the lower layer is the user. As a result, the upper layer is dependent on the lower layer. The lower layer changes, which naturally affects the upper layer, resulting in system instability, and even a pull. How can we reduce dependencies? That is, both the upper and lower layers depend on another abstraction. This abstraction is relatively stable, and the whole process is relatively stable.

B. object-oriented programming is aimed at abstraction or excuse-oriented programming. The abstraction is generally stable. The specific implementation of abstraction must depend on abstraction. abstraction should not depend on other specifics, but on abstraction.

 

In the player example above, we have found the dependency. Now we need to optimize the dependency according to the dependency inversion principle.

According to the following principles:

  • The player depends on mediafile, so that both the player and mediafile depend on an abstract imediafile.
  • Operationmain depends on the player. It is easy to implement. operationmain and player both depend on an abstract iPlayer.
  • Operationmain depends on mediafile, which is easy to handle, so that operationmain and mediafile both depend on an abstract imediafile
  • The iPlayer cannot depend on a specific mediafile. It should depend on the abstract imediafile of a specific mediafile.

The structure is very simple, so the code is roughly as follows:

/// <Summary> /// the user plays a media file /// </Summary> public class operationmain {

Public void playmedia () {imediafile _ mtype = new mediafile (); iPlayer _ player = new player (); _ player. play (_ mtype) ;}//< summary> /// player //</Summary> Public interface iPlayer {void play (imediafile file );} /// <summary> /// default player /// </Summary> public class player: iPlayer {public void play (imediafile file) {console. writeline (file. filepath) ;}/// <summary> // media file /// </Summary> Public interface imediafile {string filepath {Get; Set ;}} /// <summary> /// default media file /// </Summary> public class mediafile: imediafile {Public String filepath {Get; set ;}}

The code above is abstracted. We can see that the purpose is to reduce the dependency, but it seems that the dependency relationship has increased, such as the playmedia method, and the dependency interface and specific implementation are added, however, the interface is stable and can be ignored. The specific implementation is changed. This dependency is still required. To play a file, you must use a specific player and file.

3. Control reversal (IOC)

In real life, a specific player has nothing to do with a specific media file. You can play an MP3 file for it or an MP4 file for it, when you delete your media files, the player is still there. The control of the specific player and file to be played is all owned by our users.

The preceding example basically achieves isolation. The specific player is isolated from the specific media. The specific player is only related to the media interface and player interface. However, the specific objects in the playmedia method are hard to write, and the control is very small. If I want to use Baidu audio and video for playing, I want to change the code for a new music, how to transfer the control?

We can create through reflection and write the specific file name in the configuration file. At this time, the client code does not need to be changed. You only need to modify the configuration file, and the stability is improved as follows:

        public void PlayMedia()        {            IMediaFile _mtype = Assembly.Load(ConfigurationManager.AppSettings["AssemName"]).CreateInstance(ConfigurationManager.AppSettings["MediaName"]);            IPlayer _player = Assembly.Load(ConfigurationManager.AppSettings["AssemName"]).CreateInstance(ConfigurationManager.AppSettings["PlayerName"]);            _player.Play(_mtype);        }

Which object is controlled by the configuration file? The control of the specific object is handed over to the configuration file, which is also a common inversion of control.

Control inversion IOC is short for inversion of control. It refers to the transfer of control of an object to a third party. For example, if the transfer is made to an IOC container, it is a factory creation and what object do you want, it will give you some objects. With the IOC container, the dependency will change, and the original dependency will be gone. They all depend on the IOC container, use the IOC container to establish the relationship between them.

4. Dependency injection (DI)

The above mentioned inversion of control is an ideological concept, but it must also be implemented. The above configuration file is also an implementation method. Dependency injection puts forward specific ideas.

Dependency injection Di is short for dependency injection. It puts forward that "Which of the following controls have been reversed and transferred ?", It also gives the answer: "The creation of dependent objects is reversed ".

The so-called dependency injection means that the IOC container dynamically injects a dependency into the object during runtime.

In the preceding example, where dependency injection is required, and where the dependent object needs to obtain the instance, that is, the playmedia method, the specific object of the iPlayer and the specific object of the imediafile, should be found here, to flexibly control these two objects, the instantiation of the two objects must be controlled on the outside. It is necessary to provide external operations, such as attributes, methods, and constructors, in short, you can control it elsewhere. The following code uses unity for injection and constructor injection. The Code is as follows:

/// <Summary> /// the user plays a media file /// </Summary> public class operationmain {imediafile _ mtype; iPlayer _ player; Public operationmain (iPlayer player, imediafile mtype) {_ player = player; _ mtype = mtype;} public void playmedia () {_ player. play (_ mtype) ;}//< summary> /// player //</Summary> Public interface iPlayer {void play (imediafile file );} /// <summary> /// default player /// </Summary> public class player: iPlayer {public void play (imediafile file) {console. writeline (file. filepath) ;}/// <summary> // media file /// </Summary> Public interface imediafile {string filepath {Get; Set ;}} /// <summary> /// default media file /// </Summary> public class mediafile: imediafile {Public String filepath {Get; set ;}}

A constructor is provided for the operationmain class. Because unity has a constructor injection, the calling code is as follows:

Static unitycontainer Container = new unitycontainer (); static void Init () {container. registertype <iPlayer, player> (); container. registertype <imediafile, mediafile> ();} static void main (string [] ARGs) {Init (); operationmain OP1 = container. resolve <operationmain> (); op1.playmedia (); operationmain OP3 = container. resolve <operationmain> (); op3.playmedia (); // operationmain OP2 = new operationmain (new player (), new mediafile (); op2.playmedia (); console. read ();}

As you can see, the functions of unity are far more than that. You can register more than N during initialization and use it directly later without using new, as well as flexible control of instance cycle and configuration files, for details, refer to the description of Unity (not specifically the scope of this section.

5. Summary

By using a small example, we have optimized the IOC model from a simple perspective. I think the complicated structure is also accumulated from this simple architecture.

I have been reading related articles recently. Many of them are too professional to understand. This is my understanding of IOC and I will record it. Otherwise, I will forget it for a long time.

I am still very familiar with the IOC model. I hope you can give me some advice.

Related Keywords:

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.