Showing posts with label 程序员之路. Show all posts
Showing posts with label 程序员之路. Show all posts

Sunday, June 21, 2009

C# open folder dialog (FolderBrowserDialog)

In .Net GUI Applications, Interaction with User on selecting files is a very basic topic. In the following code samples, I have demonstrate how to select files ( in comment code), more importantly, give an example code on how to get a folder name form the windows open dialog box. Something Interesting here is that you actually can’t get the folder name easily. (I mean select a folder, you can still select the file then get the full path, which include the folder name) The best option is to use FolderBrowserDialog !

Ok, now here is the sample code. Enjoy.

        private void importToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
string startupPath = Application.StartupPath;
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
dialog.Description = "Open a folder which contains the xml output";
dialog.ShowNewFolderButton = false;
dialog.RootFolder = Environment.SpecialFolder.MyComputer;
if(dialog.ShowDialog() == DialogResult.OK)
{
string folder = dialog.SelectedPath;
foreach (string fileName in Directory.GetFiles(folder, "*.xml", SearchOption.TopDirectoryOnly))
{
SQLGenerator.GenerateSQLTransactions(Path.GetFullPath(fileName));
}
}
}
//using (OpenFileDialog dialog = new OpenFileDialog())
//{
// dialog.Filter = "xml files (*.xml)|*.xml";
// dialog.Multiselect = false;
// dialog.InitialDirectory = ".";
// dialog.Title = "Select file (only in XML format)";
// if (dialog.ShowDialog() == DialogResult.OK)
// {
// SQLGenerator.GenerateSQLTransactions(Application.StartupPath + Settings.Default.xmlFile);
// }
//}
}
catch (Exception exc)
{
MessageBox.Show("Import failed because " + exc.Message + " , please try again later.");
}

}

Tuesday, May 12, 2009

【转载】抽象的代价

转载自德明泰科技博客:http://blog.sina.com.cn/s/blog_5faf4b830100dtdy.html

随着设计模式的发展,抽象类被越来越广泛的使用。很多设计模式都要求用户接口全部使用抽象类,这样可以随意修改派生类,而维持接口不变。但是我们为此付出了什么代价呢?让我们来看一个简单的例子。

我们先定义两个类,AbstractClass与ConcreteClass,他们实现了完全一致的功能。不同的是,AbstractClass是通过派生AbstractBaseClass实现的。

class AbstractBaseClass

{

public:

virtual int func() const = 0;

};

class AbstractClass :public AbstractBaseClass

{

public:

int func() const {return 1;}

};

class ConcreteClass

{

public:

int func() const {return 1;}

};

好的,现在假设我们有一个接口需要传入一个上述class。如果我们没有使用抽象的话,我们可以直接传入一个ConcreteClass,即:

void CallConcrete(const ConcreteClass &c)

{

c.func();

}

但是在很多设计模式中,推荐像下面这样做,传入一个AbstractBaseClass类型,这样我们可以任意改动其具体实现而不影响接口。

void CallAbstract(const AbstractBaseClass& c)

{

c.func();

}

无疑,后一种方式有着好得多的可扩展性、可维护性。但是在性能上,我们付出了怎样的代价呢?让我们具体调用他们试一下。

int main()

{

AbstractBaseClass& ac = AbstractClass();

ConcreteClass cc;

CallAbstract(ac);

CallConcrete(cc);

return 0;

}

我们来看一下编译器生成的代码。

AbstractBaseClass& ac = AbstractClass();

0041157E lea ecx,[ebp-14h]

00411581 call AbstractClass::AbstractClass (411136h)

00411586 lea eax,[ebp-14h]

00411589 mov dword ptr [ac],eax

ConcreteClass cc;

CallAbstract(ac);

0041158C mov eax,dword ptr [ac]

0041158F push eax

00411590 call CallAbstract (41102Dh)

00411595 add esp,4

CallConcrete(cc);

00411598 lea eax,[cc]

0041159B push eax

0041159C call CallConcrete (41109Bh)

004115A1 add esp,4

return 0;

004115A4 xor eax,eax

从这里我们可以看得很清楚,ac由于是一个抽象类型,显然编译器是无法知道他具体需要占用多少空间的,只能在运行时在自由空间上面进行分配。而cc则是编译时完全可确定的,不需要在运行时进行分配。

两个方法调用在这里看是一样的,让我们深入函数的内部看一下,执行过程究竟有何不同。函数首尾的例行操作我这里省略了,只看关键部分。

void CallConcrete(const ConcreteClass &c)

{

c.func();

0041149E mov ecx,dword ptr [c]

004114A1 call ConcreteClass::func (4110F5h)

}

void CallAbstract(const AbstractBaseClass& c)

{

c.func();

0041143E mov eax,dword ptr [c]

00411441 mov edx,dword ptr [eax]

00411443 mov esi,esp

00411445 mov ecx,dword ptr [c]

00411448 mov eax,dword ptr [edx]

0041144A call eax

}

可以看到,在具体类的调用中,一切都很明确,编译器知道需要调用哪个函数(例子中4110F5h)。而在对抽象类的调用中,编译器就不知道究竟应该调用哪个函数了。怎么办?在代码里可以看得,c的地址被传过去了。这里究竟有什么呢?我们实际的去看一眼,这里设一个断点,可以看到c的地址。

 5faf4b83t68529a218e1e&690

c的地址位于0x415640。0x415640有什么呢?打开内存监视看一眼(不要用反汇编了,这个反汇编会搞成错误的语句)。我们看到这一行数据。

0x00415640 0e 11 41 00 00 00 00 00 70 64 41 00 6d 11 41 00 00 00 00 00 88 64 41 00 e1 10 41 00 00 00

第一条数据是0x41110E。这是什么,去看看。

0041110E E9 1D 05 00 00 jmp AbstractClass::func (411630h)

哈哈,终于找到正主AbstractClass::func了。这下明白了,这0x415640不就是传说中的虚函数表嘛!嗯,至少在VS2005编译器(我试验用的)里,一个对象最开始放的就是虚函数表。

说的有点儿远了,总结一下。当CallAbstract拿到一个AbstractBaseClass的对象c的时候,它并不知道这个c是什么类型的。调用c.func()自然也不知道该调用哪个函数。但编译器有这样一种机制,它把一个对象中实际要调用的函数地址列表(也就是虚函数表)放在了对象的一开始。于是CallAbstract方法拿到一个AbstractBaseClass的对象c之后,只需要去它的一开始去找到这个虚函数表,就能够调用正确的函数。也就是说具体调用哪个函数,CallAbstract是不知道的,但是进来的对象自己知道,这就够了。

好了,我们简单的使用了抽象类接口之后,编译器在背后帮我们做了这许多事情。比起直接使用具体类,明显复杂了不少。这就是抽象的代价了。

【转载】C++中引用的本质

转载自德明泰科技博客:http://blog.sina.com.cn/s/blog_5faf4b830100dwbd.html

一般的教材上讲到引用时,都是说“引用是对象的一个别名”。我认为这种定义是不清晰的,不利于初学者理解引用。至少我自己曾经被这个定义困扰了一段时间。到底什么是“别名”?

实际上,引用的实质是位于xxxxxx地址上的一个xxxx类型的对象。比如教科书上常用的例子:

int a = 5; //不妨假设编译器将a分配到0x400000

int &b = a;

这里面b的准确意义就是,放在0x400000地址上的一个int类型对象。这里面包括了两重含义,首先b是一个int类型对象,因此他的使用完全与int类型对象一样。另外这个int类型对象的地址是0x400000,因此从底层来看,它具有指针的一些特性,无论你怎样传递,他都代表放在0x400000的那个int。

在c++中,引用全部是const类型,定义之后不可更改。实际上“引用”对目标代码来说是不存在的,因为对于编译器来说,使用上例中的b就是使用0x400000地址的那个int。引用一经定义,就不会指向别的地址,也不会指向别的类型,因此编译器不会专门开辟空间存储这个引用,而是将发送引用的地方替换为真正的地址,接收引用的地方则替换为接受指针。

在java中,数据对象也都是引用类型,但是这里的引用与C++有很大不同,他们不是const类型,可以指向一个空值,也可以随时更改其指向的内存地址。这实际上与C++中的指针概念完全对应。java中的引用实际上对应C++中的指针而非引用,只不过是省去了C++中指针的取地址(&)与取值(*)操作。

Thursday, April 23, 2009

中小企业的项目管理方案 -- IT构架篇

德明泰作为一个专业的IT外包公司,有一套完善的项目管理方案。这一套方案是笔者在多年的工作中,集合了各色公司的精华而创立,因为知识产权的原因,不能详尽到如何配置解决,但在这里给大家介绍一下我们的管理流程和使用的工具,希望给创业团体在项目管理方面一些启示吧。

在介绍项目管理之前,就不得不提到我们的IT构架。今天首先介绍的企业局域网的架设。局域网的作用在现今这个互联网时代的作用越发重要。架设好一个适合企业的局域网,必须从企业的切实需求出发,而不是盲从的道听途说,或者聘请非专业人士。德明泰是一个面向企业提供软件IT服务的高新技术企业,我们选取的解决方案完全为企业量身定制,所以对于我们自家使用的解决方案也是千挑万选。我们从以下几个方面来考虑的:

  • 对开源系统和反盗版的支持
  • 解决方案的可重用性(打包销售给类似企业)
  • 企业的规模 (多办公地点,统一的PC管理)
  • 员工的网络自由度
  • 服务器的负载
  • 文件的集成备份

基于以上几点,我们排除了使用微软成套解决方案的可能性,而是DIY一套居于SMEServer的系统。 SMEServer是基于CentOS内核的Linux,从名字可以看出,他是一个支持中小公司的服务器,而且完全免费,有效的节约了创业初期的资金。由于服务器的操作系统选定,基于此操作系统的一系列软件配套也便完全免费了。使用开源的软件,也让我们可以方便的更改一些设置,定制出最适合企业的使用流程。通过SMEServer,对外我们将服务器作为防火墙,开设了标准的Apache+tomcat服务器。对内我们将服务器作为网关,负责内部的三个局域网(wire,wifi,openvpn)的网络服务,同时开设域名管理服务,管理企业内部标配的PC机。服务器在硬件上采用了RAID0, 并配置了不间断电源,软件上我们开发了配套不间断电源的管理软件,企业级备份软件(onsite & offsite),从两个层面保证数据的完善。同时为了减轻服务器负载,我们将系统瓶颈的IO部分单独提取出来,架设了内部文件共享系统,完美支持 SSH,SCP,FTP,Samba等多协议。

至此,我们企业的IT框架就基本成型了,接下来我会讲解一些关于我们如何构架团队协同合作工具的内容。

Wednesday, April 8, 2009

How to: Throw Custom Exception in Jax-ws

There is an excellent article on Faults and exceptions in JAX-WS, however, it doesn’t say how to throw custom exception clearly. Another post mentioned the below information, which I found most useful after google search to solve the problem. Again, it is still not correct solution.

Make the exception look like a normal JAX-WS generated exception.   That
would basically mean defining a JAXB bean for the data that has all the
getter/setters and such for the data and making the exception look like:
@WebFault
public class MyException extends Exception {
     MyFaultInfo faultInfo;
     public MyException(String msg, MyFaultInfo mfi) {
            ...
     }
     public MyFaultInfo getFaultInfo() {
         return faultInfo;
     }
}
That is basically the "JAX-WS" standard way of doing it and would be portable.  
The entire schema for the exception is defined in the JAXB MyFaultInfo bean.

If you look into jax-ws defination of @WebFault, it is basically on the client side, and was automatically generated! There is no point putting them in the server code. I had to admit that the explanation was clear and I write the following code to solve this problem

public class CustomException extends Exception {

private WSStatus faultInfo = null;

public CustomException(String message, WSStatus faultInfo)
{
super(message);
this.faultInfo = faultInfo;
}
public CustomException(String message, WSStatus faultInfo, Throwable cause)
{
super(message,cause);
this.faultInfo = faultInfo;
}

public CustomException(Exception ex)
{
super(ex.getMessage(),ex.getCause());
}

public WSStatus getErrorCode()
{
if(faultInfo==null)
faultInfo = new WSStatus();
return faultInfo;
}
}


Note that the generated code on client side would be something like CustomException_Exception extends Exception, so make sure you catch/throw the right exception.

Friday, March 27, 2009

.net interview “what is ASSEMBLIES”

INTRODUCING ASSEMBLIES
A .NET application is packaged into an assembly, which is a set of one or more files
containing types, metadata, and executable code. The .NET documentation describes
the assembly as the smallest versionable, installable unit in .NET. It is the functional
unit for code sharing and reuse. It is also at the center of .NET’s code security and
permissions model. All executable code must be part of an assembly.
When we compile a simple program, the compiler creates an assembly consisting
of a single executable file. However, assemblies can contain multiple files including
code module files and files containing resources such as GIF images. Therefore, an
assembly can be viewed as a “logical” DLL.
The assembly contains a manifest that stores metadata describing the types contained
in the assembly, and how they relate to one another. The runtime reads this
manifest to retrieve the identity of the assembly, its component files and exported
types, and information relating to other assemblies on which the assembly depends.
When an assembly consists of multiple files, one file will contain the manifest.

image

一路走来图示

zhen yang Timeline

右边链接里有个Coder’s CV,上图就是工具生成的,看起来还蛮专业的,挺有意思,呵呵。

Thursday, March 26, 2009

学习杂记 C# design pattern

Interface & Abstract class

  • Abstract class can have method that has been implemented. Can’t create an instance of abstract class. One class can only inherited from one abstract class.
  • Interface methods all must be abstract. Can’t have the implementation in the interface. A class can Inherit from multiple interface, but need to implement all its methods

UML

  • For Class Diagram, the symbols in front of the names indicate that member’s visibility, where “+” means public, “- ” means private, and “#” means protected. Static methods are shown underlined. Abstract methods may be shown in italics or, with an “{abstract}” label. Note that UML does not require that you show all of the attributes of a class, and it is usual only to show the ones of interest to the discussion at hand. clip_image002clip_image004
  • You represent inheritance using a solid line and a hollow triangular arrow. For the simple Employee class that is a subclass of Person, clip_image006
  • An interface looks much like inheritance, except that the arrow has a dotted line tail. clip_image008

Design Pattern

clip_image010

clip_image012

The Adapter pattern is used to change the interface of one class to that of

another one.

The Bridge pattern is designed to separate a class’s interface from its

implementation so you can vary or replace the implementation without

changing the client code.

The Composite pattern is a collection of objects, any one of which may be

either itself a Composite or just a leaf object.

The Decorator pattern, a class that surrounds a given class, adds new

capabilities to it and passes all the unchanged methods to the underlying

class.

The Façade pattern groups a complex set of objects and provides a new,

simpler interface to access those data.

The Flyweight pattern provides a way to limit the proliferation of small,

similar instances by moving some of the class data outside the class and

passing it in during various execution methods.

The Proxy pattern provides a simple placeholder object for a more

complex object that is in some way time consuming or expensive to

instantiate

The Single-Responsibility Principle

A class should have only one reason to change.

The Open/Closed Principle (OCP)

Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.

Wednesday, March 25, 2009

how to: Windows Form GUI application take command arguments

It is not unusual to start an GUI application with some parameters passed in through command line. We are familiar with how it the work when create a console project, but the default GUI project won’t take any parameters.

To achieve this task, you can simply edit the Program.cs:

static void Main() ==> static void Main(string[] args)

Now you can use args. This easy? Yep.

Tuesday, March 24, 2009

Deterministic Finalization in C#

这个翻译过来应该是确定性终止化。问题的关键是.net里面,这个基本是不确定的。写程序的时候时常会碰到这个问题,建议如下:

  1. 使用using
  2. 如1无效(比如没有实现IDisposable接口),则自己写一段finally{if(xxx!=null) dispose_xxx();}

看书上说这个不确定性也不一定不好,有可能更高效,但本人觉得还是需要对程序有所控制的。

Friday, March 20, 2009

[创业杂记] 项目管理

今天看到几篇文章不错,分享一下。

第一篇文章在 http://www.kuqin.com/software-engineer/20090318/40907.html

有几点比较值得注意:

1) 软件质量分内外,所以我为什么强调要注意细节,做好界面

2) 对待task需要按功能优先级,8020法则,完整性,可持续性几个方面考虑。

3) 重构的重要性。

第二篇 http://www.kuqin.com/projectmanage/20090318/40902.html

这篇纯理论,看看说不定能有点启发和感触。

Tuesday, March 17, 2009

c# how to read write excel spreedsheet

用.net读写excel文件有很多种方法,这里介绍一种比较简单的:

使用Microsoft.Office.Interop.Excel

下面是一个我项目中的一个读取函数的删减版本,要用上using Excel = Microsoft.Office.Interop.Excel;

除了读取一个Range里的东西,下面的函数演示了怎么枚举所有的行列,这样就可以不用事先知道Range了。

private void LoadExcelFile(string annotationFile)
{
Excel.Workbooks objBooks;
Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

try
{
// Instantiate Excel and start a new workbook.
objApp = new Excel.Application();
objBooks = objApp.Workbooks;
objBook = objBooks.Open(annotationFile, Missing.Value, true, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);


//Get a range of data.
range = objSheet.get_Range("A1", Missing.Value);
range = range.get_Resize(1, 1);
double videoTimeOffset = (double)range.get_Value(Missing.Value);

//Another way of getting data
string output = "";
int rowIndex = 3;
//object colIndex2 = 11;
while (((Excel.Range)objSheet.Cells[rowIndex, 1]).Value2 != null)
{
string tmp = "";
int lapID;
SwimLap.StrokeTypeEnum strokeType;
string lapType; //Warm Up/Down Main

tmp = (((Excel.Range)objSheet.Cells[rowIndex, 1]).Value2 == null) ? "-" : ((Excel.Range)objSheet.Cells[rowIndex, 1]).Value2.ToString();
if (tmp.Equals(" ") || tmp.Equals("-"))
lapID = 0;
else
lapID = Convert.ToInt32(tmp);

tmp = (((Excel.Range)objSheet.Cells[rowIndex, 2]).Value2 == null) ? "-" : ((Excel.Range)objSheet.Cells[rowIndex, 2]).Value2.ToString();
strokeType = SwimLap.GetStrokeTypeEnum(tmp);

lapType = (((Excel.Range)objSheet.Cells[rowIndex, 3]).Value2 == null) ? "-" : ((Excel.Range)objSheet.Cells[rowIndex, 3]).Value2.ToString();


SwimLap sl = new SwimLap(videoTimeOffset,lapID,strokeType,lapType,lapTime,lapVideoStartTime,lapVideoEndTime,strokeCount,confidence,isTurn,isVideoFullLap,startType,strokeRate);

ss.AddLap(sl);

rowIndex++;

}

objBooks.Close();
objApp.Quit();

}
catch (Exception theException)
{
String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat(errorMessage, theException.Message);
errorMessage = String.Concat(errorMessage, " Line: ");
errorMessage = String.Concat(errorMessage, theException.Source);
MessageBox.Show(errorMessage, "Error");
}
}

Wednesday, February 4, 2009

软件构架中对本地化的考虑

文章提出了使用.net中的资源文件来实现基本的本地化,我以前也这么用过,从构架上来说是个不错的办法。

http://www.c-sharpcorner.com/UploadFile/shivprasadk/1112301222009081643AM/11123.aspx

理解三层构架

文章在http://dotnet.csdn.net/page/08578558-7783-4e9c-ac62-05f97601331a,虽然没有讲细节案例,但是对与理解这个结构写的还行。

程序员、高级程序员、设计师、项目经理、构架师

今天突然被一个问题困扰了,就是学习了那么些书,一会儿agile,一会儿敏捷开发,到底是奔着什么去的。总说要技术nb,要做构架,到头来还没明白构架是啥。所以就翻了翻资料,英文的太长,大家估计肯定懒得看,哎,摘录一段吧,里面很清晰的阐述了构架和设计的区别。

  1. “Architecture is concerned with the selection of architectural elements, their interaction, and the constraints on those elements and their interactions…Design is concerned with the modularization and detailed interfaces of the design elements, their algorithms and procedures, and the data types needed to support the architecture and to satisfy the requirements.”
  2. Software architecture is “concerned with issues...beyond the algorithms and data structures of the computation.”
  3. “Architecture…is specifically not about…details of implementations (e.g., algorithms and data structures.)…Architectural design involves a richer collection of abstractions than is typically provided by OOD” (object-oriented design).

就我每天学的玩意来看,更多的还是偏向于设计(如设计模式,今天刚发现一个实例网站,结合理论学习之后,绝对会无敌!!!)和项目管理,但还没有把基础的程序员本质提升到高级程序员,这么看来有点太急了。大家何尝不需要想想自己要走的技术这条路,要怎么走下去,每天叼嘴边的学字,是打算怎么学?

最后附带一个中文资料网站,算是AR的入门吧,上面很多不错的文章。http://www.ibm.com/developerworks/cn/architecture/newto/