Design Mode and XP

Source: Internet
Author: User

Joshua Kerievsky, translated by Gigix
Overview
Both pattern and extreme programming (XP) provide help for Software Design and developers that cannot be measured in money. However, so far, XP has been largely concerned with refactoring, but does not mention the pattern. In this article, I asked "why" and finally described how the mode can be better implemented in XP mode, and how XP can be better implemented by using the mode of inclusion.

Thank you

 
We are very grateful to Kent Beck, Martin Fowler, and Ward cunnheim for providing friendly comments for this article.
We started our programming career when we were not very familiar with it, and the software we produced also reflected our lack of experience:
The code we created is bloated, error-prone, fragile, difficult to maintain, and difficult to expand. As time passes, we have become better software designers: we have learned from technical writers and experts, and we have learned from our own mistakes. Now we write software with high flexibility that is widely adapted and robust. When we are requested to write a new system, we know to identify current and future requirements so that we can design software to handle current and future needs.
At this stage of our software development career, eXtreme Programming tells us that we often over-engineer software. We have learned too much from our own mistakes and do not want to repeat them. So we made a lot of effort in the early stages of the system lifecycle to create flexible and robust design. Unfortunately, we do not realize that if the system never requires the flexibility and robustness of this level, all our work will be meaningless. We designed it too much.

I used to design too much. To be honest, it is a pleasure to sit in a room with other designers and think about how to design software to meet many current and future needs. We apply everything we have learned, especially the best experiences, to design.
We often know that the demand list will change, but users or customers will always change the demand. However, we think we can design software intelligently enough to make the software flexible enough to meet all the changes in demand.
Typical over-design.
Today, eXtreme Programming tells you how stupid this is. XP says we have to make the design appear, rather than predicting what the design will look like. XP said, "do the simplest thing that may work," because "you no longer need it, you no longer need it ". In addition, Kent Beck
Said:
You need to select the best way to work in a value system that emphasizes communication, simplicity, feedback, and courage, so that you can choose the best way to work in a value system that emphasizes communication, simplicity, feedback, and courage, so that you can choose the best way to work in a value system that emphasizes communication, simplicity, feedback, and courage, in this way, you can choose the best way to work in a value system that emphasizes communication, simplicity, feedback, and courage, so that you can be brave enough to break away from over-design. Brave enough to break away from excessive design. Brave enough to break away from excessive design. Brave enough to break away from excessive design. Beck1 00?
Agree. But now I must mention my friend Norm Kerth. Norm has rich experience and knowledge in software development. A year ago, I asked him "What do you think of XP ". He said:
I like everything in XP. What I care about is: there is nothing in it. Kerth 99?
At that time, I only thought Norm was a conservative. But now I am not sure. What XP obviously lacks is the experience of using the mode. Although some XP founders have helped build a pattern community, there is no clear explanation of how the pattern adapts to XP.
At the beginning, I was not confused. But now I am confused.
I am confused, because my experience in XP and pattern makes me believe that in XP scenarios, pattern works better, and when an XP package
When the mode is included, XP also works better.
This requires some explanation. I will start by describing my own usage patterns and some XP experience.
Since 1995, I began to immerse myself in the mode. My learning model document hosts a weekly model learning group, uses patterns to design and develop software, and organizes and operates UP (an international academic conference on patterns of use. It is a conservative saying that I am "keen on models.
At that time, like many first-time study models, I was a little eager to use them. This is not a good thing, because it will make your design more complex than needed. But I didn't realize this until I started learning refactoring.
Probably in 1996, I first came into contact with refactoring. I started to validate it and soon observed that refactoring took me away from some of the principles I learned in model learning.
For example, one principle in the milestone book design patterns: the basis for reusable object-oriented software is:
Programming for interfaces, rather than implementing programming. Programming for interfaces, rather than implementing programming. GHJV1 95?
The authors of design patterns have done a great job to explain why we need to follow this suggestion. In almost all models, we discuss how your software becomes less flexible and modifiable when you program a specific implementation. Almost every time I use interfaces to help.
But what if we don't need flexibility or modifyability? Why should we anticipate some things that may never happen at the beginning of the design? This is my consciousness. Then I recorded the following J AVA skills:
Do not separate classes and interfaces do not separate classes and interfaces
I used to add an "I" after my interface name ". But when I continue to learn more about refactoring technology, I began to see a wise way: design the class name and interface name as the same. The following is the reason: during the development process, you know that you can use an interface to make something flexible (to diversify the implementation), but you may not need to diversify the implementation at all. So, let go of the "over-design" with too many predictions. You still keep it simple and keep things in a class. Somewhere you will write a method statement to use the class object. Then, after a few days, weeks, or months, you explicitly "need" an interface. Therefore, you can convert the original class
Create an implementation class (implementing the new interface) and keep your original statements unchanged. Kerievsky 96?
I continue to learn courses similar to restructuring. Gradually, my usage mode began to change. I will not consider the usage mode in advance.
Now, I am more wise: If a pattern can solve a design problem, and if it provides a way to implement a requirement, I will use it, but I will start with the simplest implementation of the pattern that can be encoded. Later, I will make this implementation more flexible and stable when I need to add or modify it.
The new method of this usage mode is a better method. It saves me time and simplifies my design.
As I continued to learn more about XP, I soon began to consider the fact that those who clearly described "What is XP" and "How XP works" did not mention patterns. It seems that the focus has shifted from development to reconstruction. Construct a point, test a point, reconstruct a point, and then repeat it.
So what's wrong with the mode?
The general answer I receive is: Pattern encourages over-design, while refactoring keeps things simple and lightweight.
Now, I like refactoring like anyone else-I 've reviewed two manuscripts from Martin Fowler's book on this topic, and then I know that refactoring will become a standard. But I still like patterns. I found patterns are invaluable in "Helping people learn how to design better software. So, how can XP not include the mode ?!
I carefully wrote my anxiety on Portland Pattern Repository. I asked: should the perfect XP model be composed of programmers and instructors with completely unknown models, and should they rely entirely on refactoring to "Let code go where it should go ". Ron Jeffries, world
The most experienced XP practitioner in the world argued with me and wrote:
A beginner cannot listen to what the code says. He needs to learn the code quality model (in the general sense ). He needs a beginner who cannot listen to what the code says. He needs to learn the code quality model (in the general sense ). He needs a beginner who cannot listen to what the code says. He needs to learn the code quality model (in the general sense ). He needs a beginner who cannot listen to what the code says. He needs to learn the code quality model (in the general sense ). He needs
Optimistic code (and, I guess, poor code) so that he can learn to write good code.
One problem, I mean, is it possible that the current pattern is used to help improve the quality of the code. I think Beck's Smalltalk Best Practice Patterns will help, because those are very small models. I would like to help, because those are very small models. Design Patterns are even more skeptical, because patterns and discussions are sometimes quite large, and they may result in a much larger design pattern that looks reasonable and more questionable solutions. Martin Fowler's wonderful analysis model also has the same danger: there is also the same danger in the wonderful analysis model that can be selected: you can select a large-scale solution when selecting a small-scale solution. Jeffries 99?
A very interesting view of the model. Although I have seen that the mode can be implemented and used intelligently, Ron seems to recognize
It is dangerous for them because they "make a huge solution look reasonable ". In other places, Ron observed a common occurrence.
Emotion: How do people with their first learning model desire to use them too much.
I cannot disagree with the following observation result. Just like anything new-or even XP-people may be eager to make
Use them. But does the mode really encourage large-scale solutions when small-scale solutions are available?
I think it depends on how you define and use the mode. For example, I have observed many primary users of the pattern. They think that
Pattern is exactly the same as its structure chart (or class chart. Only when I tell them that "the mode can be implemented in different ways as needed
Now, they began to find that these graphs are only a way to represent the implementation mode.
The implementation of the mode is simple and complex. TIPS: Find out the problem that the mode is targeting, compare the problem with your current problem, and then compare the simplest implementation (solution) of this mode with your problem. When you do this, you will not use large-scale solutions when using small-scale solutions. You have achieved the best balance in solving the problem.
When people do not have good training models, difficulties may arise. Ron mentioned that people use patterns in a way that is "made up now"
-- That is to say, how do they communicate with the current author. I agree that the model document has some disadvantages. There are a lot of books on patterns. You can spend some time understanding the problems solved by patterns, so that you can select patterns Intelligently Based on your specific needs.
This choice is extremely important. If you choose the wrong model, you may be overly-designed or simply put your design together. Experienced users may also make mistakes and often see such results. However, these experts have other models that can help them face their own mistakes. Therefore, they often change the pattern they actually need to into an unsatisfactory pattern.
So how will you become an experienced model user? I found that unless people are involved in learning a lot of patterns, they may be at risk of misunderstanding, over-using them, and over-designing them.
But is this a reason to avoid using the mode?
I guess, no. I found patterns so useful in so many projects that I could not imagine using them for software design and development. I believe that the thorough learning of the model is very worthwhile.
So, does XP stay silent on patterns because it feels like they will be misused?
If this is the case, the problem may have become: How do we use the wisdom of the model, instead of how the model uses the wisdom of the model, and avoid the wisdom of the model in how we use the model, instead, how can we use the wisdom of the model, and avoid misuse of the model in development scenarios in XP development scenarios? Misuse? Misuse? Misuse?
Here, I think I have to go back to design patterns. In the "conclusion" chapter, "what will design patterns bring" section, and "reconstruction goals" section, the author writes:
Our design patterns record the design structures produced by many refactoring. Using these patterns at the beginning of the design can prevent us from recording the design structures produced by many refactoring in our design patterns. However, even after the system is built, they can still teach you how to modify your refactoring. However, even after the system is built, they can still teach you how to modify your refactoring. The Design Pattern provides a goal for your refactoring. GHJV2 95?
This is what we need: the goal of restructuring. This is the bridge between reconstruction and pattern. It perfectly describes my own progress in how to use patterns: from the very beginning, consider patterns but keep them secondary, small-scale refactoring, only when a model is needed can the reconstruction be switched to a pattern.
This process, which requires training and careful judgment, will be well adapted to the best habits of XP.
In addition, this approach is obviously different from the method of "deliberately failing to know or use the pattern but relying only on refactoring to improve the design.
The danger of relying only on refactoring is that there is no goal and people may make little progress in design, but their overall design will eventually be compromised because this approach lacks order, simplicity, and effectiveness, the smart usage mode allows developers to possess these features.
Reference Kent Beck: Mode generation architecture mode generation architecture. Beck2 94?
However, the mode does not guarantee a disciplined use. If we use them too much in design and too early, we will return to the problem of over-design. Therefore, we must answer this question: "When is the model introduced in the design lifecycle safe ?" Recall the reference to design patterns:
Using these modes at the initial stage of design can prevent future refactoring. Using these modes at the initial stage of design can prevent future refactoring. Using these modes at the initial stage of design can prevent future refactoring. Using these modes at the initial stage of design can prevent future refactoring.
This is a smart proposition. If we do not know the basic rules for "when to configure a pattern", we can easily fall into excessive design at the early stages of the design cycle.
Once again, all the problems are combined: how to match the problems in the project with a suitable pattern.
Here, I must describe my experiences in developing software for different industries.
One customer asked me and my team to build software for their website using j ava, which would be a cool interactive version. This customer does not have any j ava programmers, but still requires that the behavior of the software be modified at any time and anywhere they need, without having to make modifications in the Process Order. What a high requirement!
After some analysis on their needs, we found that the Command mode will play a very important role in this design. We will write command objects and let these command objects control the entire behavior of the software. You can parameterize these commands, sort them, and select the time and place when the command runs.
This solution works perfectly, and the Command mode is the key to success. Therefore, the Command mode is not used until the refactoring. On the contrary, we see in advance the need to use it, and from the very beginning we used the Command mode to design the software.
In another project, the system needs to run as an independent application and WEB application. The Builder mode plays a huge role in this system. Without it, I could not imagine how bloated a design would be. The Builder mode is used to solve the problem of "multi-platform and multi-environment running. Therefore, it is correct to choose it early in design.
Now, I must declare that, even if patterns were introduced early in design, they should still be implemented in the first place as they were. Mode implementation can be replaced or upgraded only when additional features are required later.
An example will help you better understand this.
The software controlled by command objects mentioned above is implemented using multi-threaded code. Sometimes two threads use the same macro command to run a series of commands. But at first we were not troubled by the thread security issue of macro commands. Therefore, when we begin to encounter the inexplicable problem caused by thread security, we must reconsider our implementation. The question is, should we take the time to construct the thread security of macro commands? Or is there a simpler way to solve this problem?
We solve this problem in a simpler way and avoid over-design: Provide an independent macro command instance for each thread.
We can implement this solution within 30 seconds. Compare the time with the time required to design a thread-safe macro command.
This example describes how XP's philosophy keeps things simple when using patterns. Without such a simple driver, the sub-design solution-like the macro command of thread security-is easy to appear.
Therefore, it is important to simplify the connection with the mode.
When programmers need to make design decisions, one important thing is that they should try to keep the design simple, because simple design is usually easier to maintain and expand than a large and complex design. We already know that refactoring means keeping us on the simple road: it inspires us to gradually improve our design in small but simple steps and avoid over-design.
But what about the mode? Aren't they helping us keep things simple?
Some may say "no ". They believe that patterns, although useful, are easy to cause complicated design. They think that the pattern will result in a rapid increase of objects and excessive dependency on Object combinations.
This is due to incorrect understanding of the usage mode. Experienced users can avoid complex designs, rapid object growth, and excessive object combinations.
In fact, experienced users make the design easier when using the mode. I will use another example to illustrate my point of view.
JUnit is a simple and useful j ava testing framework written by Kent Beck and Erich Gamma. This is a wonderful piece of software, which is full of well-selected simple models.
Recently, some people have asked me to DeGo JUnit? F. That is to say, remove the design patterns in JUnit to observe what JUnit looks like. This is a very interesting exercise because it allows participants to seriously consider when to introduce patterns in the system.
In order to describe what they learned, we will DeGo some extensions in JUnit 2.1? F.
JUnit has an abstract class named Test Case. All specific Test classes are derived from it. TestCase? Class does not provide any method to run the test multiple times, nor does it provide a method to run the test in its own thread. Erich and Kent use the Decorator mode to elegantly implement repeatable and thread-based tests. But what if the design team does not know the Decorator mode? Let's see what they will develop and evaluate how simple their design is.
This is what Test Case looks like in JUnit Framework 1.0 (for simplicity, annotations and many methods are ignored ):

-------------------------------------------------------------------------------- 1
2 public abstract class TestCase implements Test {
3 private String fName;
4 public TestCase (String name ){
5 fName = name;
6}
7 public void run (TestResult result ){
8 result. startTest (this );
9 setUp ();
10 try {
11 runTest ();
12}
13 catch (AssertionFailedError e ){
14 result. addFailure (this, e );
15}
16 catch (Throwable e ){
17 result. addError (this, e );
18} tearDown ();
19 result. endTest (this );
20}
21 public TestResult run (){
22 TestResult result = defaultResult ();
23 run (result );
24 return result;
25}
26 protected void runTest () throws Throwable {
27 Method runMethod = null;
28 try {
29 runMethod = getClass (). getMethod (fName, new Class [0]);
30} catch (NoSuchMethodException e ){
31 e. fillInStackTrace ();
32 throw e;
33}
34 try {
35 runMethod. invoke (this, new Class [0]);
36}
37 catch (InvocationTargetException e ){
38 e. fillInStackTrace ();
39 throw e. getTargetException ();
40}
41 catch (IllegalAccessException e ){
42 e. fillInStackTrace ();
43 throw e;
44}
45}
46 public int countTestCases (){
47 return 1;
48}
49}
--------------------------------------------------------------------------------

New requirements require repeated tests, or in their respective threads, or both.
Inexperienced programmers generally perform subcategorization when encountering such new requirements. But here, because we know TestCase? Objects will need to be able to run repeatedly in the same thread or in separate threads, so programmers know that they need to consider more.
One way is to add all the functions to TestCase? Itself. Many developers, especially those who do not understand the design pattern, will do so without considering that this will make their classes bloated. They must add features, so they add the features to any areas that can be added. The following code may be their implementation:

-------------------------------------------------------------------------------- 1
2 public abstract class TestCase implements Test {
3 private String fName;
4 private int fRepeatTimes;
5 public TestCase (String name ){
6 this (name, 0 );
7}
8 public TestCase (String name, int repeatTimes ){
9 fName = name;
10 fRepeatTimes = repeatTimes;
11}
12 public void run (TestResult result ){
13 for (int I = 0; I <fRepeatTimes; I ++ ){
14 result. startTest (this );
15 setUp ();
16 try {
17 runTest ();
18}
19 catch (AssertionFailedError e ){
20 result. addFailure (this, e );
21}
22 catch (Throwable e ){
23 result. addError (this, e );
24}
25 tearDown ();
26 result. endTest (this );
27}
28}
29 public int countTestCases (){
30 return fRepeatTimes;
31}
32}
--------------------------------------------------------------------------------

Note the run (TestResult? Result) the method is larger. Are they still TestCase? Class added another constructor. So far, this is not a big deal. In addition, we can say that if this is all the things that must be done, using the Decorator mode is redundant.
Now, if you want to make every TestCase? How does an object run in its own thread? There is also a possible implementation:

-------------------------------------------------------------------------------- 1
2 public abstract class TestCase implements Test {
3 private String fName;
4 private int fRepeatTimes;
5 private boolean fThreaded;
6 public TestCase (String name ){
7 this (name, 0, false );
8}
9 public TestCase (String name, int repeatTimes ){
10 this (name, repeatTimes, false );
11}
12 public TestCase (String name, int repeatTimes, boolean threaded ){
13 fName = name;
14 fRepeatTimes = repeatTimes;
15 fThreaded = threaded;
16}
17 public void run (TestResult result ){
18 if (fThreaded ){
19 final TestResult finalResult = result;
20 final Test thisTest = this;
21 Thread t = new Thread (){
22 public void run (){
23 for (int I = 0; I <fRepeatTimes; I ++ ){
24 finalResult. startTest (thisTest );
25 setUp ();
26 try {
27 runTest ();
28}
29 catch (AssertionFailedError e ){
30 finalResult. addFailure (thisTest, e );
31}
32 catch (Throwable e ){
33 finalResult. addError (thisTest, e );
34} tearDown ();
35 finalResult. endTest (thisTest );
36}
37}
38 };
39 t. start ();
40 result = finalResult;
41} else {
42 for (int I = 0; I <fRepeatTimes; I ++ ){
43 result. startTest (this );
44 setUp ();
45 try {
46 runTest ();
47}
48 catch (AssertionFailedError e ){
49 result. addFailure (this, e );
50}
51 catch (Throwable e ){
52 result. addError (this, e );
53} tearDown ();
54 result. endTest (this );
55}
56}
57}
58 public int countTestCases (){
59 return fRepeatTimes;
60}
61}
--------------------------------------------------------------------------------

Well, it looks worse. To support two new features, we now have three constructor and run
(TestResult? Result) The size of the method expands rapidly.
Even with all the new code, our programmers have not yet met these needs: we still cannot repeat the test in their respective threads. For this purpose, we must add more code. Forget it. Let me leave you alone.
Refactoring helps reduce the size of the Code. But we only need to think a little bit: What should we do if we receive another new requirement?
Currently, JUnit 3.1 supports four different TestCase types? Modifier, which can be easily combined to obtain the required functions. At the same time, the implementation of JUnit is still simple-there is no messy code. This design makes the Test Case class simple and lightweight. You only need
Wait for TestCase? Objects can be decorated, and any combination order can be selected.
It is clear that this is an example of a pattern that helps simplify the design. This example also shows how inexperienced developers can improve their design-if they know the reconstruction goal stated by the pattern.
It is smart to use patterns to develop software, but it may also be dangerous if you lack experience in using patterns. For this reason,
I strongly advocate model learning groups. These learning groups allow people to steadily move forward and master patterns with the help of their peers.
When people understand patterns and use them in trained ways, patterns are the most useful-This trained method is XP. In the XP mode, developers are encouraged to keep the design simple and reconstruct the mode as needed. It encourages key models in the early stages of design. It encourages matching the problem with the pattern that can help solve the problem. Finally, it encourages developers to write simple implementations of models and then develop them as needed.
In the XP scenario, the mode is indeed more useful. In the use of the mode, XP development is more likely to succeed.
Bibliography reference

[Beck1 00] Beck, Kent. Email on extremeprogramming@egroups.com, January 2000.
[Beck2 94] Patterns Generate ubuntures, Kent Beck and Ralph Johnson, ECOOP 94
[GHJV1 95] Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard
Helm, Ralph Johnson and John Vlissides. Chinese Translation: Design Pattern: Reusable basics of object-oriented software, translated by Li.
[GHJV2 95] Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard
Helm, Ralph Johnson and John Vlissides. Pages 353-354 Chinese Translation: design patterns: the basis for reusable object-oriented software,
Translated by Li Yingjun, Chapter 2.

[Jeffries 99] Jeffries, Ron. Patterns And Extreme Programming. Portland Pattern Repository. December,
1999
[Kerth 99] Kerth, Norm. Conversation, circa March, 1999.
[Kerievsky 96] Kerievsky, Joshua. Don't Distinguish Between Classes And Interfaces. Portland Pattern

Repository. Circa 1996

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.