Talk from an instance OOP, factory model and reconstruction

xiaoxiao2021-03-06  37

"Let the stiff wings fly" series of two - discuss Adapter mode from an example

"Let the stiff wings fly" series - from Adapter mode to Decorator mode

With wings, it can fly, lack of flexible code is like a bird who is frozen wings. If you can't fly, you will have a few alert rhyme. We need to bring the code to warm sunshine, let the stiff wings fly. Combined with examples, by applying OOP, design patterns and reconstruction, you will see how the code is a step in step.

In order to better understand design ideas, examples are as simplified as possible. But as demand increases, the program will become more complicated. At this time, there is a need for modifying design, and you can send it to the field. Finally, when the design is gradually perfect, you will find that even if the demand is increasing, you can also get angry, don't worry about the code design.

Assume that we want to design a media player. The media player currently only supports audio files MP3 and WAV. If you don't talk about design, the designed player may be simple: public class mediaPlayer {private void playmp3 () {MessageBox.show ("Play the mp3 file.");}

Private void Playwav () {MessageBox.show ("Play The WAV File.");}

Public void play (String Audiotype) {Switch (Audiotype.tolower ()) {CASE ("MP3"): PlayMP3 (); Break; Case ("WAV"): Playwav (); Break;}}}

Nature, you will find this design very bad. Because it does not provide the minimum extension for future demand changes. If your design results are like this, then when you focus on the needs of the need to change the demand, you may want to make this design to the place where it should go, is the desktop recycle bin. Carefully analyze this code, which is actually the oldest facing design. If you want to play more than just MP3 and WAV, you will continue to add the corresponding playback method, then let the Switch clause grow longer and getting up to the point you can't see.

Ok, let's first experience the spirit of the object. According to OOP, we should regard MP3 and WAV as an independent object. So is this? Public class mp3 {public void play () {MessageBox.show ("Play The MP3 File.");}}

Public Class WAV {Public Void Play () {MessageBox.show ("Play The WAV File.");}}

Good, you already know how to build an object. More gratifying is that you have applied reconstructed methods in unknown, change the name of the method in that garbage design to a unified Play () method. You will find how the name is the key in the design! But it seems that you have not hit the hit, change the code of MediaPlayer in the present way, and there is not much change.

Since MP3 and WAV belong to audio files, they all have the commonality of audio files, why not establish a common parent class for them? Public class audiomedia {public void play () {MessageBox.show ("Play The audiomedia file.");}} Now we introduce inheritance ideas, OOP is also an image image. If you are proud, you still analyze the real world. In fact, in real life, we play only a specific type of audio file, so this Audiomedia class is not actually used. Corresponding to the design, this is never instantiated. Therefore, I have to move the surgery and change it to an abstract class. Ok, now the code is a bit OOP feeling: public abstract class audiomedia {public abstract void play ();}

Public class mp3: audiomedia {public override void play () {MessageBox.show ("Play the MP3 File.");}}

Public Class WAV: Audiomedia {Public Override Void Play () {MessageBox.show ("Play The WAV File.");}}

Public class MediaPlayer {public void play (audiomedia media) {media.play ();}}

Look at the current designs, you meet the level of relationships between classes, but also guarantee the minimization principles of classes, more beneficial to expand (here, you will find more than possible Play methods). Even if you add playback to the WMA file, you only need to design the WMA class, and inherit the Audiomedia, you can rewote the Play method, the Play method of the MediaPlayer class object does not have to change.

Is it a satisfactory date? Then the customers who are drilled are never satisfied, they are complaining about this media player. Because they don't want to watch the football game, I only heard the host's commentary, they are more eager to see the football star running in the stadium. That is, they want your media player to support video files. You have this painful, because when you change the hardware design, the original software design structure seems to have problems. Because video files and audio files have many different places, you can't be lazy, let video file objects recognize audio files make your father. You need to design additional class objects for the video file, assume that we support the video of RM and MPEG format: public abstract class videoedia {public abstract void play ();}

Public class rm: videomedia {public override void play () {MessageBox.show ("Play The RM File.");}}

Public class mpeg: videomedia {public override void play () {MessageBox.show ("Play The Mpeg File.");}}

Worse, you can't enjoy the original MediaPlayer class for all. Because the RM file you want to play is not a subclass of Audiomedia.

But you don't have to worry, because you haven't used this shark (although you can also use abstract classes, you only support class inheritance in C #). Although video and audio formats are different, don't forget, they are all kinds of media, many times, they have many similar features, such as playing. According to the definition of the interface, you can implement a series of objects of the same functionality to the same interface: public interface iMedia {void play ();} public abstract class audiomedia: iMedia {public abstract void play ();

Public Abstract Class Video Videomedia: iMedia {public Abstract Void Play ();

Change the MediaPlayer's design is OK: public class mediaplayer {public void play (iMedia Media) {media.play ();}}

Now you can summarize, from the evolution of MediaPlayer classes, we can conclude that when calling the properties and methods of the class object, try to avoid the specific class object as a pass parameter, but should pass its abstract object, better Transfer interface, completely peel off the actual calls and specific objects, which improves the flexibility of the code.

However, things did not finish. Although everything looks perfect, we ignore this fact is to forget MediaPlayer's caller. Remember the first Switch statement in the article? It seems that we have been very beautiful to remove this trouble. In fact, I played a trick here, delaying the Switch statement. Although in MediaPlayer, the code looks clean and neat, in fact, the trouble is just the transfer of MediaPlayer's caller. For example, in the main program interface: public void btnplay_click (object sender, Eventargs e) {switch (cbbmediatype.selectItem.toT7tring (). TOLOWER ()) {iMedia Media; case ("mp3"): Media = new MP3 () Break; Case ("WAV"): Media = New WAV (); Break; // Other type = new MediaPlayer Player = New MediaPlayer (); Player.Play (Media);} User By selecting the options for the CBBMediatype box Determine which file is played, and then click the Play button to execute.

The design pattern is now debuted, which creates different types of ways according to different situations, and the factory model is the most hand. Let's take a look at which products do our factories need to produce? Although there are two different types of media Audiomedia and Videomedia (more later), they also implement the IMEDIA interface, so we can treat it as a product and use the factory method mode. The first is the factory interface: public interface imediafactory {iMedia createmedia ();

Then for each media objects to build a factory, the factory interface and implement uniform: public class MP3MediaFactory: IMediaFactory {public IMedia CreateMedia () {return new MP3 ();}} public class RMMediaFactory: IMediaFactory {public IMedia CreateMedia () {return New rm ();}} // other factory slightly; Writing here, maybe someone will ask, why not build a factory directly to Audiomedia and Videomedia classes? It is very simple, because in Audiomedia and Videomedia, there are different types of derivation. If you build a factory for them, you still have to use the Switch statement in the createMedia () method. And since these two classes have realize the Imedia interface, they can be considered a type. Why should I invoke abstract factory models to generate two types of products?

There may be someone asking, even if you use this way, do you want to use the Switch statement when you judge which factory created? I acknowledge this view is right. However, the factory model is used, and its direct benefits are not to solve the problem of the Switch statement, but to delay the generation of the object to ensure the flexibility of the code. Of course, I still have the last killing hand, didn't make it out, and later you will find that the Switch statement is actually completely disappeared.

There is also a problem, is it really necessary to achieve two abstract classes of Audiomedia and VIDEOMEDIA? Let the subclasses directly implement the interface is not simpler? For the needs mentioned in this article, I think you are right, but don't rule out that Audiomedia and Videomedia will also have differences. For example, the audio file only needs to provide an interface to the sound card, and the video file also needs to provide an interface to the graphics card. If MP3, WAV, RM, MPEG directly implements the IMEDIA interface, and not through Audiomedia and Videomedia, it is not reasonable to meet other needs. Of course, this is not included in this article.

Now there is a slight change in the main program interface: public void btnplay_click (object sender, evenetargs e) {iMediafactory factory = null; switch (cbbmediatype.selectItem.tostring (). TOLOWER ()) {CASE ("mp3": factory = New mp3mediafactory (); break; case ("wav"): factory = new wavmediafactory (); break; // Other type = new MediaPlayer Player = new MediaPlayer (); player.play (factory.createMedia ());}

Writing here, we will return to the head to see the MediaPlayer class. In this class, the Play method is implemented, and the PLAY method of the corresponding media file is called according to the passing parameters. When there is no factory object, it seems that this type of object is very good. If it is as a class library or component designer, he provides an interface for main interface staff calls. However, after the introduction of factory mode, it has been used in the MediaPlayer class. Therefore, we have to remember that reconstruction is not just to add new content to the original code. When we find some unnecessary design, we need to delete these redundant code decisively. Public void BtnPlay_Click (object sender, EventArgs e) {IMediaFactory factory = null; switch (cbbMediaType.SelectItem.ToString () ToLower ().) {Case ( "mp3"): factory = new MP3MediaFactory (); break; case ( " WAV "): factory = new wavmediafactory (); break; // Other type} iMedia Media = factory.createmedia (); Media.Play ();} If you don't experience the benefits of iMedia interface, Here you should already understand. We use this interface in the factory; and in the main program, it is still necessary to use the interface. What is the benefit of using an interface? That is, your main program can also compile the pass when there is no specific business class. Therefore, even if you add new business, your main program is not changed.

However, it seems that this does not have to change the ideal of the master, still not finished. see it? In btnplay_click (), some instances of specific classes are created with NEW. If there is no complete and specific class, once the specific class is changed, for example, the new factory class is added, and there is still a need to change the main program. What hate the Switch statement still exists. It seems to be a toxic tumor that has been breed on wings, prompting us, Although the wings have been resurrected from the stiffen world, this pair of wings are still sick, and they don't fly normally.

It is when using the configuration file. We can put the corresponding information of each media file class in the configuration file, then select the specific object based on the configuration file. Also, this method of creating an object will be done using reflection. First, create a configuration file:

Then, in the Form_Load event of the main program interface, read all Key values ​​of the configuration file, populate the CBBMediaType combination box control: public void form_load (Object sender, Eventargs E) {cbbmediatype.Items.clear (); Foreach (String Key in) ConfigurationSettings.AppSettings.AllKeys) {cbbMediaType.Item.Add (key);} cbbMediaType.SelectedIndex = 0;} Finally, the main change Play button click event: Public void BtnPlay_Click (object sender, EventArgs e) {string mediaType = cbbMediaType.SelectItem.ToString () ToLower ();. string factoryDllName = ConfigurationSettings.AppSettings [mediaType] .ToString (); IMediaFactory factory = (IMediaFactory) Activator.CreateInstance ( "MediaLibrary", factoryDllName) .Unwrap (); // MediaLibray For the collection of media files and factories; iMedia Media = factory.createmedia (); Media.Play ();

Now the bird's wings are not only resurrected, there is a flying ability; we also give this pair of wings stronger features, it can fly higher, farther!

Enjoy free flying. Imagine if we want to add playback features of some media file, such as an AVI file. Then, we only need to create an AVI class in the original business assembly and implement the IMEDIA interface while inheriting the Videomedia class. In addition, create an AvimediaFactory class in the factory business and implement an iMediaFactory interface. Suppose this new factory type is WingProject.avifactory, add the following line in the configuration file: . And what about the main program? Don't do any changes at all, don't even need to recompile, this pair of wings can be fly freely!

For example, please click here to download.

Posted on 2004-11-29 15:08 Wayfarer reading (1103)

Comments (29)

edit

Collect

comment

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 16:10

Yuanlm

How to use the upper reflex mechanism, the coated factories are not available, only one attribute is in each specific class.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 16:50

Wayfarer

This is actually two design methods. Because the factory model is easy to create specific products, it feels more flexible. Main reasons or I prefer to use factory models. Small new translational articles "Attributes" and activation mechanisms to implement factory model ", use Attribute. The link address is:

Http://www2.cnblogs.com/wdxinren/archive/2004/11/25/68775.html

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 17: 34PAUL

It's good to write, thank you.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 17:53

Ask

I am not deeply used by the model, ask:

One typical factory model is to access different databases and can be changed in the configuration file, but the premise is that the code has been accessed by different databases.

And in this example, it does not write a good time to write an operation code for different media files. If you need a new type of Play, you need to modify the factory and configuration files, if I don't have to profile but in the Switch of the main program. If the plus code is, the two are also modified two places. It is also to recompile the program. Why do I have to use a configuration file in the same "trouble"?

Maybe I ask questions around a big circle, the main meaning is: Where is the advantage of using a configuration file? In the case of increasing new factory classes, use or do not need to configure file modified amounts, why said that the modification of the main program became this pair of wings or sick?

Rookie question, I hope everyone Haihan :)

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 18:36

Wayfarer

Oh :) This problem is very interesting. In fact, I was thinking about this issue. So how do you experience the profile of profile? For examples of this article, it should be two layers of distribution. One is a layer, one is a business layer. Indicates that the layer is our main program, which provides an interface for user operation. The business layer includes the operation of the specific media file and factory class.

If you create a specific class object directly in the main program and pass the Switch statement, then when you increase your business needs, you need to modify the layer and the business layer and recompile. The method introduced herein will only change the class library file of the business layer, and the indication layer does not have to change. This reflects the spirit of layering and loose coupling.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 18:38

Yok

Wrong word: Video is video is not vedio

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 19:32

Wayfarer

Oh, I will modify it immediately, thank you Yok.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 20:55

Small new 0574

Nice article, in fact, I am doing a similar small software learning, I have some problems when class design, your article solves some of my doubts, thank you!

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 23:37

Xiaohui

Now I see the reflection, I thought of the performance of everyone.

Talk to Tiger Color? Oh.

This article writes easy to understand. Good articles. :)

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-29 23:44

Ice steam

It's so good ~ step by step, thank you

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-30 10:11

Lu Zhenyu

It is very attractive to see the topic, but there is no time to read today, first collect it, read again.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-30 10:57

CHANNELV

Really good, I have finished reading in the morning, have a further understanding of OOP, plant models and refactors, thank you for the landlord!

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-30 11:33 Desert Lonely

Good article, praise

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-11-30 16:15

QQ'Richer

It is really great, and the concept of blurred concept is clear. PFPF

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 15:43

Dljsoft

Not bad!

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 15:51

Ice steam

Wayfarer Hello

Go back to write the code according to your ideas, I feel very interesting, my thinking is a lot.

It also draws a UML diagram according to the structure, but there is a problem, what should the DE relationship between the MP3MediaFactory class and IMEDIA interfaces should be? How to explain on the class diagram? Thank you

It is because MP3 inherits Audiomedia

Public Class Mp3: Audiomedia {}

Audiomedia inherits from the IMEDIA interface

Public Abstract Class Audiomedia: IMEDIA {}

So, even if the type of CreateMedia method defined by the MP3MediaFactory class is IMEDIA, it is still possible to return an IMEDIA subclass - MP3 class. right?

Thank you

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 16:26

Wayfarer

@ 冰汽水:

Here, the MP3 class indirectly implements the IMEDIA interface. So the factory is created when creating an MP3 object, although it returns iMedia, but according to the polymorphism, it is determined by the polymorphism. When it is running, it will regard the IMEDIA object as an MP3 object.

So when you call the iMedia.play () method, it will consider the MP3 Play method when you run.

Your UML map is correct. Of course, according to the needs of this article, the MP3, RM and other classes can be implemented directly, without having to add Audiomedia and Videomedia abstract classes. The reason why it is designed, it is also considered from the perspective of architecture, and it feels more reasonable.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 16:41

Ice steam

@Wayfarer

I get it, thank. Very appreciate your writing style.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 19:48

Woodball

The heroes are really powerful, wonderful!

◎ Ice Steam:

1. Ask, what kind of tool is your UML picture? Is Rose? How can my Rose can't use this font? How to set it?

2. Is it inheritance or realization for an abstract class?

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 20:06

Wayfarer

Look at the style of the picture, it should be Rose. In short, it will not be Visio.

For class, it is called inheritance; it is called implementation for the interface.

I am answering :)

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-01 21:28

Ice steam

@ Wooden ball:

I am using Rational Xde for .NET, because the design changes can be reflected in the code in the code, and it feels easier to get started.

@wayfarer:

I think the best in this design idea is that after implementing the factory interface, you can return a business interface that has been implemented, then do business operation directly. #

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-02 10:50

Lu Zhenyu

Today, I read it, very good. To See a World in A Grain of Sand (see a world from a sand).

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-06 13:10

Wayfarer

The code for reading the configuration file is slightly wrong, and changes have been made. And provide source code download.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-11 01:56

Smallland

What is the use of factory models that cannot be seen too narrow. Perhaps from a programmer's perspective to use some way to improve the complexity of the problem he faced, causing the efficiency of his work to decline. Effects should be considered as a whole.

For example: Customers give you a request, he said that the program is going to run on "IE5, IE6, Netscape7 and other browser". This "waiting" word may bring a lot of trouble to your design work, which will become a risk in demand. what would you do? Can you ask the customer to determine which browsers in the end, otherwise the design cannot be completed. Maybe the response to your customers will still be unclear, this is a common situation. You can also try to make the design more flexible, one side to confirm, and start working.

For example, you have designed a browser interface, all business scripts are running on this interface. This interface has different implementations on IE or Netscape, and instantiation of the interface is responsible by a factory. In this way, you release the coupling between business code and actual browser, once this "wait" is really a trouble, you don't have to find all the code, and just add an implementation.

Application will accompany demand from simple to complex, and good design can provide a relatively smooth road for this development.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2004-12-22 13:41

faith

Great

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2005-01-05 20:30

Ice steam

What if I want RM, MPGE class has some of my own specific properties?

Factory.createMedia Returns an IMEDIA type object, while iMedia only has a Play method, if an attribute is defined in iMedia, then RM, MPEG must have these properties.

To make these products have different properties outside of the same way, please give pointers.

#

Re: Let the stiff wings fly - discuss OOP, factory model and reconstruction from an example

2005-01-05 21:56

Wayfarer

@ 冰 汽水

Your problem is very good. If there is such a situation, simply modify the configuration file. Of course, the prerequisite for this article is that this interface should be used as a common interface, and the client calls a public behavior.

I thought about it, perhaps adapter mode, it should be better. For the original design, it is small. That is, the specific behavior of the RM, the MPEG class (you said attributes, but I think it is better to behave better) Define the interface, such as ISPECIALMEDIA, then use Adapter mode to implement the interface.

When you create an IMEDIA class through a factory, by determining whether its class object is an ISPECIALMEDIA interface, if it is displayed to the ISPECIALMEDIA type, it is OK.

You remind me that after I tried, I may write articles.

#

Re: "Let the stiff wings fly" series - discuss OOP, factory model and reconstruction from an example 2005-01-17 02:03

Ice steam

@Wayfarer

I was busy with work a few days ago, I have read a series of two to five tonight. I feel that the harvest is not small. But I saw a bit of indigestion behind, beyond my understanding. So I still returned here to continue my simple problem.

In fact, I have the requirements of "Different Behavior of Subclasses" above is to use the factory model to encapsulate a DB operation class. The reason is to learn a variety of modes to yourself. I hope to simplify the .NET. OLEDB class.

It is simplified, and I want to go to it, I have encapsulated the connection string of DB. In the actual development process, we often write to the connection string based on the way the database is connected and the database. For example: Even a library should consider using OLEDB (Jet 4.0) or ODBC, and then consider whether the target database is Oracle or SQL Server or something else.

So, I want to write a class, put the above classification, although this is not necessarily effective.

I wrote some code a few days ago, I found that there is a feature in addition to some of the following elements, I don't know if there is any suitable design mode.

1. A iDatabase interface (equivalent to IMEDIA) defines an operation such as Connection, Close, Begin. Here, I will conclude that the host program is the same as the database of various needs. Of course, there is still a DBFActory factory class, implement the CreateDatabase method (similar to iMediaFactory)

2. A Database abstraction class, implement the various methods of the Idatabase interface (equivalent to videomedia)

3. Different from the "Player" example, this structure has more subclasses such as OLEDB and ODBC below the Database base class. They inherit from the Database base class, which is because these two connection methods are Define different or the same properties, such as the OLEDB defined: dbpath, username, password ...; and ODBC defined: odbcname, username, password .......

4. On the OLEDB or ODBC, the specific Oracle, SQLServer, Access, and they are truly concrete to implement Connection, Open, and Close methods. (The problem is here, then said later)

In this way, the Client end is implemented in accordance with different needs:

DBFActory = new oraclefactory ();

or

DBFActory = New SQLSerFactory ();

after that

Then the CONNECTIONTYPE attribute of DBFActory is assigned, and then a DB instance is obtained by the CreateDatabase method, and after the different attributes of this instance, the connection objects such as the Connection are used to get the DB connection object, and then begind Begin ... Close. .

When I finished thinking about my thinking today, if this structure, I must have a different attribute that I must have different properties in real time after the following series of processing.

DBFActory = new oraclefactory (); // <- What type of target database is

DBFActory.connectionType = "OLEDB" // <- What connection method can also be defined here to define an enumeration variable

/ / Then get a DB instance

Idatabase DB = dbfactory.createdTabase (); 5. At this time, the DB instance should be able to have different properties according to dBFactory.ConnectionType = "OLEDB" or DBFactory.ConnectionType = "ODBC" (above NO.3 mention DBPATH, Username, Password ... or odbcname, username, password is used.

The problem is on step No.5, what kind of pattern can make these Oracle, SQLServer class dynamic with different properties?

(These subclasses must be not related to the attributes of OLEDB or ODBC, they just implement all the consistency of all DBs)

Say a lot, I don't know if it is clear. I will post some UML or code for you later, and I may know more about my thoughts.

Really, I think about it today, this actual significance of this package is not necessarily large, only learning.

Thank you! !

Attached: The series of admiration for your "let the stiff wings fly" series, give me this kind of beginner with a very clear guidance, I hope that one day can catch up with everyone.

转载请注明原文地址:https://www.9cbs.com/read-67000.html

New Post(0)