|
Cheeky to post the discussion of friends, I hope friends do not mind
A:
To start a discussion, I'll start with a brick. Today I saw the section on implementing Functor in the new thinking of C ++ design. I feel that GP is more suitable for class library design than system design.
First of all, talk about the advantages of GP. I personally think that the main advantages of GP are code reuse, execution efficiency, type safety, and ease of use. And this is exactly what the class library design needs. As a large system, code reuse is less important. The key is to reduce the complexity of the design, reduce the difficulty of maintenance, and scalability.
Personally, I think the GP is not doing well in this regard. As far as design is concerned, it is difficult to write good generic code. Too much consideration of using GP to make the code reusable will increase the complexity of the design. The maintainability of generic code is not as good as OO, especially those more sophisticated generic code, it takes a long time to understand.
Secondly, GP will not only increase the complexity of system design. As for designing class libraries, it is more difficult to use GP. Personally, one of the reasons for the difficulty in designing C ++ class libraries is not the multi-paradigm of C ++, but because of the class. Library design is overly enthusiastic about GP.
In terms of reusability, it is incomplete to say that GP has better reusability. The reusability of GP is reflected in the fact that various types can simply reuse components in some class libraries as long as they meet certain requirements. There is no advantage to those functional reuse. For example, I need an FTP class for data transmission. For the reuse of FTP class, GP has no advantage.
As far as execution efficiency is concerned, it is also the class library design that is more concerned. For system design, according to the two and eight theorems, the efficiency improvement brought by GP is not too important.
B:
As a large system, code reuse is less important
---
I don't agree with this. If you don't reuse, it will produce a lot of duplicate, similar code, which is a very serious problem, which has a great adverse impact on development efficiency, product quality, and difficulty of maintenance.
It is difficult to write high-quality GP code, but I think that any degree of reuse requires a degree. If you talk about writing GP code, you must be able to cross-platform, have high efficiency, and have good behaviors for various types. , Wait, I'm afraid few people can accomplish this. Not only is GP difficult, even OO is even harder.
There is no conflict between OO and GP. It depends on where they are applicable. GP is suitable for writing libraries. It is difficult to write libraries. In particular, efficiency and elegance of design are often contradictory. GP can achieve a better balance.
A:
Any reuse requires a degree. If you write GP code, you must be able to cross-platform, have high efficiency, and have good behaviors for various types, etc. I am afraid few people can accomplish this. Not only is GP difficult, even OO is even harder.
------------------------------------------
Agree, I just want to know the application level of GP in actual work. For me, it feels a little difficult to combine GP and OO programming. Represent different modes of thinking. I personally think that GP is an abstraction of the relationship between objects and behaviors, and OO is an abstraction of the relationship between objects and objects. It feels that OO is very important to encapsulate the data and behavior of the object, but GP is to separate the type and behavior. Although this is not contradictory, and I don't like pure OO, I feel that it is difficult to program the combination of the two (this may be my own reason, and my own programming experience is seriously inadequate :)) Of course, there are a lot of Encapsulation and inheritance are used, but I personally think that this is not a combination of OO and GP programming.
The topic is far away :), I want to ask whether GP can reduce the complexity of large-scale system design. Although there is no "silver bullet" in software engineering, I feel that OO does reduce the complexity of system design to a certain extent. Considering GP in system design will increase complexity.
The power of GP in the design of class libraries is obvious to all. This is not only reflected in the design of low-level applications. For GUI libraries such as WTL, the compiled program size is much smaller than the MFC program with the same function. It feels easier to use.
I personally feel that GP is more like a small framework, but it is a bit inappropriate. It provides the basic framework of tools and generation tools, and OO is more suitable for system development on this basis.
My personal humble opinion, once again drew a lot of attention :)
-------------------------------------------------- -------------------------------------------------- -------------------------------------- B:
I feel exactly the opposite of you :) I think OO will increase complexity and GP can reduce complexity.
Class inheritance will become more complicated in the future. The inheritance relationship is a very strong coupling. Good design avoids abuse of inheritance. GP decouples types, which is a higher level of abstraction than OO. This is of great benefit to reduce the complexity of the entire system (of course, the GP technology itself seems to be much more complicated than OO).
When you say that GP is like a small framework, I don't agree with it. I think GP is more like a very independent "component". It can be used by assembling it and has great flexibility. Not as rigid as the so-called framework.
Speaking of actual work, I am afraid that there are not many opportunities to use GP. Didn't you read the discussion on verysource, even STL was not allowed, because I was afraid that others in the group could not understand it. . . Although I disagree with this view, the reality is that there are only a few C ++ programmers who know GP.
The combination of OO and GP ideas you said is difficult. After all, it is still a matter of degree. When it should be separated, it should be separated. When it is encapsulated, the design of std :: string is not as big as Daniel said that it is too. Are you fat? Many member functions can be separated. But there are still many people who say that the functions it seals are too few and are not easy to use. It can be seen that it is really difficult to grasp this degree. Different users, different levels, different views.
B:
In addition, regarding the design of the string, I think that we should minimize the member functions of the string class, reuse the functions that can decouple the types, and then write a fat_string to combine the string class, plus all members that are convenient for users. Functions, the internal implementation can use those independent reuse functions. This can meet the needs of different users.
A:
Class inheritance levels will become more complicated in the future. The inheritance relationship is a very strong coupling. Good design avoids abuse of inheritance.
--------------------------------------
Agree, OO is most commonly used for encapsulation, not for derivation, and too many levels of inheritance can cause unmanageable complexity. However, proper control of the inheritance level, and the use of inheritance in a reasonable place can control the complexity. If inheritance is used, it is likely to require polymorphism. For example, when dealing with a collection of heterogeneous objects, individuals decide that OO should do better.
#include <iostream>
#include <vector>
#include <boost / shared_ptr.hpp>
using namespace std;
using namespace boost;
class IBASE
{
public:
virtual void doSomething () const = 0;
virtual ~ IBASE () {};
};
class DeA: public IBASE
{
public:
void doSomething () const {cout << "DeA" << endl;}
};
class DeB: public IBASE
{
public:
void doSomething () const {cout << "DeB" << endl;}
};
int main ()
{
typedef vector <shared_ptr <IBASE>> IBASEVec;
IBASEVec vec;
vec.push_back (shared_ptr <IBASE> (new DeA));
vec.push_back (shared_ptr <IBASE> (new DeB));
for (IBASEVec :: iterator iter = vec.begin ();
iter! = vec.end ();
++ iter)
{
(* iter)-> doSomething ();
}
} |
|