分享
 
 
 

Simple Programming Tip #1 by Charlie Calvert

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Welcome bear

www.borland.com

AppServer

C++

CORBA

CaliberRM

Delphi & Kylix

InterBase

JDataStore

Java

Star Team

Together

Simple Programming Tip #1 by Charlie Calvert

Abstract: This article contains the explication of a simple programming tip that can be read in a few minutes: Avoid writing code that does anything substantial inside a visual container. Instead, create separate classes for your working code.

Simple Programming Tip #1 by Charlie Calvert

Copyright ?2003 by Charlie Calvert

In this article I will describe the first of several simple programming tips. The discussion and code in this article is generic, and applies equally to C++, CSharp, Delphi or Java programmers.

The tip for this article is easy to describe: Avoid writing code that does anything substantial inside a visual container such as a Java JPanel or JDialog, or a Delphi/C++Builder TForm or TFrame. Instead, write code inside separate classes designed for a single, simple purpose.

Of course there are times when it is appropriate to break any rule. After all, what is the point of having a rule, if there won't be occasions when you break it? Needless to say, the smaller and simpler your application, the less need there is for rules of this type. But in big applications, rules like this are the keys to the kingdom!

The Danger of Click and Code

Borland was among the companies that pioneered the now popular options that allow you to drop a component such as button on a visual container, then double click on that component, and immediately begin writing event handling code. The beauty of this system is that it allows you to write code quickly and easily. The danger is that it can lead you down the primrose path that leads to unmaintainable "write once, read never" code.

The solution, of course, is not to abandon visual programming, but rather to adopt intelligent programming. When you create a new visual container, the first thing you should do is create at least one secondary class designed to contain your real code.

Suppose, for instance, that you want to create a visual container that will allow the user to view data. In particular, suppose your container will show the results of parsing an XML file that contains information about the Voyager I and II spacecraft.

Data of this kind is likely to be fairly complex. For instance, you would want to provide controls for seeing data that applies to Voyager I only, or to Voyager II only. Likewise, you would want to allow the user to see data about a particular planet visited by the spacecraft, such as Jupiter, Saturn, or Neptune.

Without going into details, it is easy to see that you are going to have to write a substantial amount of code that involves extracting data from your XML file. The neophyte visual programmer will write that code directly inside a button response method:

void MyButtonResponseMethod_actionPerformed(ActionEvent e)

{

// Code to parse file added here

}

Suppose the code inside this method allows you to sort data according to the planet you are interested in investigating. The programmer happily writes a few lines of SAX based code, and seemingly has a solution to their problem.

But it is precisely at this moment that the ax falls. Whomp! Down it comes, cutting off the programmer of a large project from any hope of ever writing code that can be maintained or reused.

Let's follow this hapless programmer just a little further, to see the extend of the damage. The next step in this application's development might be to add a routine for displaying data sorted by findings made exclusively by either Voyager I or Voyager II. So another button response method is created, and now the user has two options:

Sort by planet

Sort by spacecraft

So far so good. But what if the user wants to simultaneously sort by spacecraft and by planet? The all too common solution to this problem is to create a third button response method that contains rewrites of the code in the Sort by planet response method and the Sort by spacecraft response method! This is a disastrous situation, in which duplicate chunks of code begin to appear. If a bug is found in the Sort by planet method, then the fix will also have to be applied to the duplicate code found in the Sort by spacecraft and planet method.

Some will laugh and say: "Oh, but I would never do anything so stupid!" And yet, I assure you, intelligent people do things exactly that foolish.

But let us suppose that the programmer is wise enough not to make such an error. Seeing the problem on the horizon, they move the code for sorting by spacecraft and planet to their own unique methods inside the visual container class. In pseudo code, the declaration for such a class might look something like this:

public class MyVisualContainer

{

void _SortByPlanet_actionPerformed(ActionEvent e)

void _SortBySpacecraft_actionPerformed(ActionEvent e)

void SortByPlanet()

void SortBySpacecraft()

void SortByPlanetAndSpaceCraft_actionPerformed(ActionEvent e)

}

The problem here is that the MyVisualContainer class is already starting to take on too heavy a burden! Like Dr. Jekyll and Mr. Hyde, it is beginning to lead a double life. Is it a simple visual container, or is it a XML parser? Only its hairdresser knows for sure!

The proper structure for code of this type should look something like this:

public class MyVisualContainer

{

void _SortByPlanet_actionPerformed(ActionEvent e)

void _SortBySpacecraft_actionPerformed(ActionEvent e)

void SortByPlanetAndSpaceCraft_actionPerformed(ActionEvent e)

}

public class MyVoyagerParser

{

void SortByPlanet()

void SortBySpacecraft()

void SortByPlanetAndSpaceCraft();

}

The methods inside the container should feature only a few lines of code that call the working code in MyVoyagerParser. With today's compilers and CPU's, the overhead of adding this extra class will not cause a noticeable, or in many cases even measurable, hit to the performance of your application. As mentioned earlier, the best course of action is to block out the declaration fro MyVoyagerParser right at the start, as soon as you open the source for MyVisualContainer.

The Advantages of Intelligent Programming

In the previous section, I outlined some of the dangers of adding complex code to the button or menu event handlers. Let's now talk about some of the advantages of this type of coding.

Suppose you want to reuse the code you have written in a new application with a different interface. If you wrote your code properly, then your port to a new type of application will be easy. For instance, in the example at the end of the last section, you could simply reuse the MyVoyagerParse class. Just plug it in to your new app, calling it with a few simple lines of code:

MyVoyageParse->SortByPlanet();

But reuse is only half the story. The other big advantage of this type of programming is that it helps you simplify your code.

We have already seen that a visual container class can quickly become overburdened by trying to support too much functionality. Consider what happens if you want to add a totally new type of functionality to your container. For instance, suppose you wanted to write some code that reported on the Deep Space Network (DSN) that is used to send commands and communicate with the Voyager spacecraft.

The worst case scenario would occur if a programmer starting adding code of this type to the original visual container:

public class MyVisualContainer

{

void _SortByPlanet_actionPerformed(ActionEvent e)

void _SortBySpacecraft_actionPerformed(ActionEvent e)

void SortByPlanet()

void SortBySpacecraft()

void SortByPlanetAndSpaceCraft_actionPerformed(ActionEvent e)

void DSNCommand_actionPerformed(ActionEvent e)

void DSNTransmission_actionPerformed(ActionEvent e)

void SortDSNCommunicationsByCommand()

void SortDSNCommunicationsByTransimmision()

}

Note the two methods at the end of the new version of the MyVisualContainer class. This poor over wrought class is now forced to take on a third (or is it a fourth?) responsibility! And as the program grows, yet more tasks will be assigned to MyVisualContainer. Pity the poor programmer who comes on board to sort all this out.

The obvious solution is to create three class: MyVisualContainer, MyVoyagerParser, and MyDSNParser. A new programmer brought on to this project could immediately find the code that is associated with the DSN part of the project, and could test and debug the code via an isolated set of routines.

The Tricky Bits

In all fairness, I should point out that there are some difficulties with the technique described here. In particular, to promote reuse, one should thoroughly separate the code in the working class from the visual programming code.

Suppose the Sort by Planet class needed to create a list of strings to be displayed in a list box. If the list box is in the visual container, how will the MyVoyagerParser class access it?

The worst solution to this problem is to pass in a copy of the list box itself. Instead, you should pass in the list that will be displayed in the list box. For Delphi and C++Builder programmers, that means that you need to pass in a TStrings object. Java programmers would want to pass in a DefaultListModel or perhaps an array of strings.

Other methods in the MyVoyagerParser class might be designed to return a string or integer that can be assigned to an edit control or label by the MyVisualContainer class. In other cases, you may need to come up with custom data structures. Languages like Java that support model view architectures make this part of your task easy.

In practice, I enjoy writing code that makes it possible for my working classes to share data with my visual containers. In most cases, solutions are easy to find. The results are easily reusable classes that fit together with clock like precision.

Conclusion

In this article you have learned one simple technique you can use to help you write code that is easy to maintain, and easy to reuse. The points shared in this article may seem obvious, but ironically, it is often the most intelligent programmers who are most prone to make these kinds of errors. A "natural" programmer with a great memory can easily sort out a huge amorphous chunk of code. For instance, they can cope with the class beginning to take shape in the last version of MyVisualContainer. Even if we added fifty more methods to the class, and had it take on five or six new roles, still, a really sharp witted programmer could sort it all out. They could make it all work, and they could find all the bugs in it and ship it so that it ran cleanly.

However, not even the smart programmer would be able to solve the problems that arose when it was time to morph the code so that it fit a new type of project. For instance, I've seen some very smart programmers resort to horrendous hacks when trying to port Windows code to Linux, standard Delphi or C++ code to the .NET platform, or Delphi or C++ code to Java. In many cases, the primary problem was simply that they were working with visual containers that were hopelessly overburdened. At times like that, even the best programmers could benefit from the simple tip covered in this article: Never place a substantial body of code in a visual container! Instead write code in separate classes designed for a single, simple purpose.

Add or View comments on this article

NOTE: The views and information expressed in this document represent those of its author(s) who are solely responsible for its content. Borland does not make or give any representation or warranty with respect to such content.

Article ID: 30011 Publish Date: May 01, 2003 Last Modified: May 01, 2003

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有