Am 08.08.14 18:08, schrieb pmqt71: > ... > @Oliver: > yes my problem is that QLineEdit can have only 1 validator. I think > inherithance should be easier than implementin a ChainValidator, am I right?
We could now fill pages of discussions about "Inheritance being evil", "is-a" vs "has-a" vs "uses-a" relations etc., and we'd end up having at least 10 times more opinions than possible ways of implementing the solution ;) (Just start by asking Google with "Inheritance is Evil" - and you get the idea ;)) Here is just a starter link: http://en.wikipedia.org/wiki/Composition_over_inheritance Personally I try to question inheritance as much as possible. The classic question is "Is a Square also a Rectangle"? The best practical explanation - and design question you should ask yourself whenever you have inheritance in mind - I ever read is: would an instance of a derived class pass all (possible and sensible) unit tests of a base class? Let's continue with the "Shall I derive my Square class from the Rectangle class?"-example (which is really a classic, but as such probably also of "academic value") and let us further assume there was a unit test which would verify the "area" method. So the test would look something like: int width = 3; int height = 5; Rectangle rect; // setup rect->setWidth(width); rect->setHeight(height); // exercise int area = rect.area(); // verify assert(area, width * height); Now if you ran the same test, but with an instance of Square, that test would fail! Why? Because our expectation is that whenever you modify either width or height, the implementation of a Square would implicitly set the height or width respective to the same value (otherwise the instance would not be a square!). So after setting the height to 5, the width in above example would also become 5 and the area would be 25 != 15. Fail. Now would e.g. a UPPERCaseValidator inherited from a LettersOnlyValidator also falsify unit tests in the same way? Most likely. There is another reason why particularly in this example I would definitively opt for the "ChainValidator" (-> composition): it is way more flexible! Let's assume you had 3 validators A, B and C and an additional "UPPERCaseValidator" (4 classes in total). If you wanted to have for each A, B, C Validator a combination, you'd have to come up with another 3 classes (deriving each time from A, B and C respective)! So that would be 7 classes in total to maintain (and if you need to fix something in your UPPERCaseValidator implementation, you'd need to fix it 3 times in the worst case - you could share parts of the implementation, but still...). With a composition pattern you'd only need one extra class - a "ChainValidator" - and you could combine either A, B or C with your UPPERCaseValidator. Only one additional class, total 5 classes. "Well, 5 or 7 classes", what's the big deal anyway! Well, here is the deal: just add one more validator D, and your number of classes grows linearily (and so are the number of implementations to maintain): not only do you have another class D, but also a new derived class from D - total 9 classes! For every "base validator" class that you'd add you would have to implement yet another derived class (assuming off course that this would make sense to have an UPPERCaseValidator also validate the output of all A, B, C and D classes). But here's an even bigger deal: Let's assume your boss now tells you that you need to validate A, B - AND C! Or any combination thereof (boss: "Oh and yes, off course, don't forget about our new shiny UPPERCaseValidator class, add that to the mix, too! And the new validator D that we just purchased yesterday..."). So would you want to come up with classes such as ABCUpperCaseValidator, CBAUpperCaseValidator, AUpperCaseValidator, BUpperCaseValidator, CUpperCaseValidator, ... (the names reflect the "inheritance chain")? Hopefully not! A combinatorial explosion of possible inheritance permutations! With the "ChainValidator" however you would simply assemble the validators like so (pseudo-syntax - you get the idea): AValidator a; BValidator b; CValidator c; UPPERCaseValidator d; ChainValidator ca; // validates a and d ca.add(a); ca.add(d); state = ca.validate(theString, pos); ca.clear(); // validats a, c and d ca.add(a); ca.add(c); ca.add(d); ca.validate(theOtherString, pos); No need to come up with new classes! And just one single UPPERCaseValidator implementation! (Again, whether the above actually works when it comes to validation, I don't know - clearly there would be combinations which would not make sense at all, but in the worst case you'd probably just get an Invalid state with /any/ input). Now all that said: the above might be complete "over-engineering" in your particular case! If you have 2 or 3 very specific cases to validate "in just that particular dialog" and "I will never ever have the need to ever re-use those inhertited validation classes anywhere - I swear!" then go for inheritance - it is not "per se evil" ;) Just know the consequences. Cheers, Oliver _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest