Convert multiplication to addition from csdn Longshanks)

Source: Internet
Author: User

Do not get it wrong, instead of using addition to reload operator *. (The programmer should be dismissed immediately ). Or anything related to computing. Here is another story.
When you read this post, have you ever thought about how your computer is made up? Memory, motherboard, hard disk, CPU, video card, display, optical drive, keyboard, mouse, etc. Yes, you must be familiar with it. So, have you ever wondered how many accessories a computer manufacturer has prepared to make computers with different configurations? Sorry, I don't know. But it doesn't matter. We can assume that. Assume that the memory specifications are 256, 512, 1g, and 2g (the same is true if the brands are not considered ); there are five hard drive types: 80g, 100g, 120G, G, and G. There are three types of video cards (I don't know how many types of video cards are available if I assume) and five types of CPU; there are 4 types of displays, 5 types of optical drives, and no mouse or keyboard considerations.
How many configurations can we get in total? Very simple, 4*5*3*5*4*5 = 6000! Of course, no manufacturer will launch the 6000 model, just let's assume. How many accessories are there in total? 4 + 5 + 3 + 5 + 4 + 5 = 26. That is, the manufacturer only needs to manage 26 types of accessories to create 6000 models.
Now let's assume that when IBM invented the PC, it was a bit confused and didn't componentialize all components of the PC. All components were soldered to a circuit board, includes displays. If a vendor wants to obtain these 6000 types of computers, they must directly produce and manage 6000 different components (computers ).
This is the difference. componentized vs non-componentized: 26-6000.
Now, let's get back to the familiar software (development. We usually face the same problem as computer vendors in software development: product diversity. Even for the same software, different customers usually have different requirements. Developing different software for each customer is obviously very inefficient. (Unfortunately, this stupid behavior has almost become a convention in the industry ). By the way, customers here refer to people who use your software. If you develop a database, the customer is the person who uses your database. This article focuses on library development.
Suppose we want to develop a packaging library for database access. It provides other programmers with the ability to access databases conveniently and quickly, so that they do not have to deal with difficult ODBC or oledb. However, the premise is that our packaging library cannot compromise the access capability of developers like ado.net.
Based on this premise, we need to consider several basic elements of database access. I have summarized the following: cursor, data binding, and data buffering. For simplicity, other details are not taken into consideration. At the same time, only the processing part of the result set is considered. Below, we will examine two different implementation methods: Oop and GP.
First look at the OOP method. The OOP method uses polymorphism and later binding to provide scalability and consistent interfaces. The code will probably look like this:
Class mydbaccessor
{
...
Virtual bool movenext ();
Virtual bool movepre ();
Virtual bool movefirst ();
Virtual bool movelast ();

Virtual bool getdata (const string & field, void ** data );
Virtual bool getdata (INT field, void ** data );
Virtual bool setdata (const string & field, void * Data ){...}
Virtual bool setdata (INT field, void * Data ){...}

Virtual void bindcolumn (const string & field, dbtype type );
Virtual void bindcolumn (INT field, dbtype type );

PRIVATE:
Virtual void defaultbind () = 0;
...
};
Because only the program structure is concerned here, only the declaration is given and the definition is omitted. Mydbaccessor defines a basic framework that supports different features, such as different cursors. It is implemented by reloading the corresponding virtual functions in the inheritance class:
Class mydbffaccessor // fast-forward cursor type
: Public mydbaccessor
{
...
Virtual bool movenext (){...}
Virtual bool movepre (){...}
Virtual bool movefirst (){...}
Virtual bool movelast (){...}
...
};
Then, when we need a database access class that supports fast-forward cursor, automatic binding, and row-based buffer, we define the following classes:
Class mydb_ff_dyn_row
: Public mydbaccessor
{
...
Virtual bool movenext (){...}
Virtual bool movepre (){...}
Virtual bool movefirst (){...}
Virtual bool movelast (){...}

Virtual bool getdata (const string & field, void ** data ){...}
Virtual bool getdata (INT field, void ** data ){...}
Virtual bool setdata (const string & field, void * Data ){...}
Virtual bool setdata (INT field, void * Data ){...}

PRIVATE:
Virtual void defaultbind (){...}
...
};
If we need a database category class that supports dynamic cursor, string binding (all types are converted to strings), and block buffering, we need to define another inheritance class.
The problem is that there are at least eight types of cursors. Suppose there are five default binding methods (automatic, wide/narrow string binding, XML binding, and manual binding ), there are three data buffering methods (row buffering, block buffering, and array buffering ).
How many inheritance classes do we need to define? 8*5*3 + 1 = 121. Mission Impossible, unless you have resources like Ms.
Now, let's see if the GP method is better. First, we define a class template:
Template <class cursor, class binder, class rowbuffer>
Class mydbaccessor
: Public cursor, public binder, public rowbuffer
{
...
};
The template mydbaccessor inherits from the template type parameters cursor, binder, and rowbuffer. The three template parameters correspond to the cursor management class, binding class, and row buffer class respectively. Based on the preceding assumptions, we have defined eight types of cursor management classes:
Class fastforwardcursor
{
Public:
Bool movenext ();
Bool movelast ();
Bool getdata (const string & field, void ** data );
Bool getdata (INT field, void ** data );
Bool setdata (const string & field, void * Data ){...}
Bool setdata (INT field, void * Data ){...}
};
Class fastforwardreadonlycursor
{
Public:
Bool movenext ();
Bool movelast ();
Bool getdata (const string & field, void ** data );
Bool getdata (INT field, void ** data );
};
...
Class dynamiccursor
{
Public;
Bool movenext ();
Bool movepre ();
Bool movelast ();
Bool movefirst ();
Bool getdata (const string & field, void ** data );
Bool getdata (INT field, void ** data );
Bool setdata (const string & field, void * Data ){...}
Bool setdata (INT field, void * Data ){...}
};
Careful people will find that the interfaces (member declarations) of these cursor management classes are different and will tell you why later.
Other binding classes and data buffering classes are defined in sequence. When we need a database access class that supports the fast-forward cursor and is automatically bound and buffered by row, we only need to use the corresponding class instantiation template:
Mydbaccessor <fastforwardcursor, dynamicbinder, singlerowbuffer> da;
...
If we need a database shard class that supports dynamic cursor, string binding (convert all types to strings), and fast buffering, it is also very convenient:
Mydbaccessor <dynamiccursor, stringbinder, bulkbuffer> da;
...
In the GP mode, we only need to define 8 + 5 + 3 + 1 = 17 classes and templates to achieve the effect of 121 class definitions in the OOP mode.
Very good. More than that. Suppose you want to access the database with a dynamiccursor cursor, but the error is as follows:
Mydbaccessor <fastforwardcursor, dynamicbinder, singlerowbuffer> da;
...
Da. movefirst (); // ah!
Don't tell me that you won't make such a low-level mistake. This kind of error occurs all the time. The most likely case is that the software design is changed from fast-forward cursor to dynamic cursor, but you forgot to modify the da statement.
At this time, the code will not be compiled. Because mydbaccessor inherits from the cursor management class and inherits the member functions that manipulate the cursor from the cursor management class. Therefore, according to the definition of fast-forward, there is no movefirst () function (or not, right ). Therefore, mydbaccessor <fastforwardcursor, dynamicbinder, singlerowbuffer> does not have this function. Then Da. movefirst () will cause a compilation error.
Many beginners may not like this design because they are very afraid of compiler errors. It's like the compiler is a Chinese teacher in their middle school. In fact, you should be grateful for this compilation error, which helps you eliminate a potential bug as soon as possible. If we add the movefirst () function in fastforwardcursor, compilation will naturally be fine. However, during running, this code will certainly cause a runtime error. If you are lucky, it may happen when your customer is in the worst mood. This consequence ,..., Sorry.
In addition, even when you test, you will be forced to track the cause of the problem with dozens or even hundreds of steps, so that your weekend dating girlfriend's mood is broken. & #61514;
All right, the multiplication and addition method is complete. Simply put, you can use templates, inherited template parameters, and multi-inheritance techniques to combine some basic elements to form a complex and fully functional class. Use the least code to do the most. This technology was proposed by Andrei Alexander resu, a pioneer in the C ++ field. It is called policy. For more details, refer to mow.c ++ design, which provides detailed explanations and cases. However, you must be prepared to accept a large dose template.

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.