问:
Why are pointers not recommended when coding with C++?
I read from somewhere that when using C++ it is recommended not to use pointers. Why is pointers such a bad idea when you are using C++. For C programmers that are used to using pointers, what is the better alternative and approach in C++?</p>

答:
Talking about VC6, when you cast a pointer of a class (that you instantiate) into a variable (e.g. DWORD), even if this pointer is local you can access the class over all the functions that use the same heap. The instantiated class is defined as local but in fact it is not.
As far as I know, any address of a heap variable, structure or class is unique along all the life of the hosting class.

Example:

```<code>class MyClass1 {
    public:
        void A (void);
        void B (void);
        void C (void);
    private:
        DWORD dwclass;
};

class MyClass2 {
    public:
        int C (int i);
};

void MyClass1::A (void) {
    MyClass2 *myclass= new MyClass2;
    dwclass=(DWORD)myclass;
}

void MyClass1::B (void) {
    MyClass2 *myclass= (MyClass2 *)dwclass;
    int i = myclass->C(0); // or int i=((MyClass2 *)dwclass)->C(0);
}

void MyClass1::B (void) {
    MyClass2 *myclass= (MyClass2 *)dwclass;
    delete myclass;
}
</code>```

EDIT Thats a very little part of the original code. The CSRecodset class is only a casting class of CXdbRecordset, where all the real code is. Doing so I can let the user take benefit of what I wrote without loosing my rights. I do not pretend to demonstrate that my database engine is professional but it really works.

```<code>//-------------------------------------
class CSRecordSet : public CSObject
//-------------------------------------
{
public:
    CSRecordSet();
    virtual ~CSRecordSet();
    // Constructor
    bool Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef);
    //Open, find, close
    int OpenRst(bool bReadBlanks=0,bool bCheckLastSql=0,bool bForceLoad=0,bool bMessage=1);     // for a given SQL
    int FindRecord(bool bNext);         // for a given SQL
    // TABLE must be ordered by the same fields that will be seek
    bool SeekRecord(int nFieldIndex, char *key, int length=0);  // CRT bsearch
    bool SeekRecord(int nFieldIndex, long key);
    bool SeekRecord(int nFieldIndex, double key, int decimals);
    bool SeekRecord(XSEK *SEK);
    bool DeleteRecord(void);
    bool Close(void);
    // Record Position:
    bool IsEOF(void);           // pointer out of bound
    bool IsLAST(void);          // TRUE if last record
    bool IsBOF(void);           // pointer out of bound
    bool IsOpen(void);
    bool Move(long lRows);      // returns FALSE if out of bound
    void MoveNextNotEof(void);  // eof is tested
    void MoveNext(void);        // eof is not tested
    void MovePrev(void);        // bof is tested
    void MoveLast(void);
    void MoveFirst(void);
    void SetAbsolutePosition(long lRows);
    long GetAbsolutePosition(void);
    void GoToLast(void); // Restore position after a Filter
    // Table info
    long GetRecordCount(void);
    int GetRstTableNumber(void);
    int GetRecordLength(void); //includes stamp (sizeof char)
    int GetTableType(void);
    // Field info
    int GetFieldCount(void);
    void GetFieldName(int nFieldIndex, char *pbuffer);
    int GetFieldIndex(const char *sFieldName);
    int GetFieldSize(int nFieldIndex);
    int GetFieldDGSize(int nFieldIndex); // String size (i.e. dg_Boolean)
    long GetRecordID(void);
    int GetStandardFieldCount(void);
    bool IsMemoFileTable(void);
    bool IsNumberField(int nFieldIndex);
    int GetFieldType(int nFieldIndex);
    // Read Field value
    bool GetFieldValue(int nFieldIndex, XdbVar& var);
    bool GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer);
    char *GetMemoField(int nMemoFieldIndex, char *pbuffer, int buf_size);
    bool GetBinaryField(unsigned char *buffer,long *buf_size);
    // Write Field value
    void Edit(void); // required
    bool SetFieldValue(int nFieldIndex, XdbVar& var);
    bool SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer);
    bool Update(void); // required
    // pointer to the same lpSql
    LPXSQL GetSQL(void);
};

//---------------------------------------------------
CSRecordSet::CSRecordSet(){
//---------------------------------------------------
    pClass |= (CS_bAttach);
}
CSRecordSet::~CSRecordSet(){
    if(pObject) delete (CXdbRecordset*)pObject;
}
bool CSRecordSet::Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef){
    CXdbQueryDef *qr=(CXdbQueryDef*)pQueryDef->GetObject();
    CXdbTables *db=(CXdbTables*)pDataBase->GetObject();
    CXdbRecordset *rst = new CXdbRecordset(db,qr);
    if(rst==NULL) return 0;
    pObject = (unsigned long) rst;
    return 1;
}
bool CSRecordSet::Close(void){
    return ((CXdbRecordset*)pObject)->Close();
}
int CSRecordSet::OpenRst(bool bReadBlanks,bool bCheckLastSql,bool bForceLoad, bool bMessage){
    unsigned long dw=0L;
    if(bReadBlanks) dw|=SQL_bReadBlanks;
    if(bCheckLastSql) dw|=SQL_bCheckLastSql;
    if(bMessage) dw|=SQL_bRstMessage;
    if(bForceLoad) dw|=SQL_bForceLoad;

    return ((CXdbRecordset*)pObject)->OpenEx(dw);
}
int CSRecordSet::FindRecord(bool bNext){
    return ((CXdbRecordset*)pObject)->FindRecordEx(bNext);
}
bool CSRecordSet::DeleteRecord(void){
    return ((CXdbRecordset*)pObject)->DeleteEx();
}
bool CSRecordSet::IsEOF(void){
    return ((CXdbRecordset*)pObject)->IsEOF();
}
bool CSRecordSet::IsLAST(void){
    return ((CXdbRecordset*)pObject)->IsLAST();
}
bool CSRecordSet::IsBOF(void){
    return ((CXdbRecordset*)pObject)->IsBOF();
}
bool CSRecordSet::IsOpen(void){
    return ((CXdbRecordset*)pObject)->IsOpen();
}
bool CSRecordSet::Move(long lRows){
    return ((CXdbRecordset*)pObject)->MoveEx(lRows);
}
void CSRecordSet::MoveNextNotEof(void){
    ((CXdbRecordset*)pObject)->MoveNextNotEof();
}
void CSRecordSet::MoveNext(void){
    ((CXdbRecordset*)pObject)->MoveNext();
}
void CSRecordSet::MovePrev(void){
    ((CXdbRecordset*)pObject)->MovePrev();
}
void CSRecordSet::MoveLast(void){
    ((CXdbRecordset*)pObject)->MoveLast();
}
void CSRecordSet::MoveFirst(void){
    ((CXdbRecordset*)pObject)->MoveFirst();
}
void CSRecordSet::SetAbsolutePosition(long lRows){
    ((CXdbRecordset*)pObject)->SetAbsolutePosition(lRows);
}
long CSRecordSet::GetAbsolutePosition(void){
    return ((CXdbRecordset*)pObject)->m_AbsolutePosition;
}
long CSRecordSet::GetRecordCount(void){
    return ((CXdbRecordset*)pObject)->GetRecordCount();
}
int CSRecordSet::GetFieldCount(void){
    return ((CXdbRecordset*)pObject)->GetFieldCount();
}
int CSRecordSet::GetRstTableNumber(void){
    return ((CXdbRecordset*)pObject)->GetRstTableNumber();
}
void CSRecordSet::GetFieldName(int nFieldIndex, char *pbuffer){
    ((CXdbRecordset*)pObject)->GetFieldName(nFieldIndex,pbuffer);
}
int CSRecordSet::GetFieldIndex(const char *sFieldName){
    return ((CXdbRecordset*)pObject)->GetFieldIndex(sFieldName);
}
bool CSRecordSet::IsMemoFileTable(void){
    return ((CXdbRecordset*)pObject)->IsMemoFileTable();
}
bool CSRecordSet::IsNumberField(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->IsNumberField(nFieldIndex);
}
bool CSRecordSet::GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer){
    return ((CXdbRecordset*)pObject)->GetFieldValueIntoBuffer(nFieldIndex,pbuffer);
}
void CSRecordSet::Edit(void){
    ((CXdbRecordset*)pObject)->Edit();
}
bool CSRecordSet::Update(void){
    return ((CXdbRecordset*)pObject)->Update();
}
bool CSRecordSet::SetFieldValue(int nFieldIndex, XdbVar& var){
    return ((CXdbRecordset*)pObject)->SetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer){
    return ((CXdbRecordset*)pObject)->SetFieldValueFromBuffer(nFieldIndex,pbuffer);
}
bool CSRecordSet::GetFieldValue(int nFieldIndex, XdbVar& var){
    return ((CXdbRecordset*)pObject)->GetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SeekRecord(XSEK *SEK){
    return ((CXdbRecordset*)pObject)->TableSeek(SEK);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,char *key, int length){
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,key,length);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,long i){
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,i);
}
bool CSRecordSet::SeekRecord(int nFieldIndex, double d, int decimals)
{
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,d,decimals);
}
int CSRecordSet::GetRecordLength(void){
    return ((CXdbRecordset*)pObject)->GetRecordLength();
}
char *CSRecordSet::GetMemoField(int nMemoFieldIndex,char *pbuffer, int BUFFER_SIZE){
    return ((CXdbRecordset*)pObject)->GetMemoField(nMemoFieldIndex,pbuffer,BUFFER_SIZE);
}
bool CSRecordSet::GetBinaryField(unsigned char *buffer,long *buf_size){
    return ((CXdbRecordset*)pObject)->GetBinaryField(buffer,buf_size);
}
LPXSQL CSRecordSet::GetSQL(void){
    return ((CXdbRecordset*)pObject)->GetSQL();
}
void CSRecordSet::GoToLast(void){
    ((CXdbRecordset*)pObject)->GoToLast();
}
long CSRecordSet::GetRecordID(void){
    return ((CXdbRecordset*)pObject)->GetRecordID();
}
int CSRecordSet::GetStandardFieldCount(void){
    return ((CXdbRecordset*)pObject)->GetStandardFieldCount();
}
int CSRecordSet::GetTableType(void){
    return ((CXdbRecordset*)pObject)->GetTableType();
}
int CSRecordSet::GetFieldType(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldType(nFieldIndex);
}
int CSRecordSet::GetFieldDGSize(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldDGSize(nFieldIndex);
}
int CSRecordSet::GetFieldSize(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldSize(nFieldIndex);
}
</code>```

EDIT: requested by DeadMG:

```<code>void nimportequoidumomentquecaroule(void) {

    short i = -4;
    unsigned short j=(unsigned short)i;

}
</code>```

Body:
Talking about VC6, when you cast a pointer of a class (that you instantiate) into a variable (e.g. DWORD), even if this pointer is local you can access the class over all the functions that use the same heap. The instantiated class is defined as local but in fact it is not.
As far as I know, any address of a heap variable, structure or class is unique along all the life of the hosting class.

Example:

class MyClass1 {
    public:
        void A (void);
        void B (void);
        void C (void);
    private:
        DWORD dwclass;
};

class MyClass2 {
    public:
        int C (int i);
};

void MyClass1::A (void) {
    MyClass2 *myclass= new MyClass2;
    dwclass=(DWORD)myclass;
}

void MyClass1::B (void) {
    MyClass2 *myclass= (MyClass2 *)dwclass;
    int i = myclass->C(0); // or int i=((MyClass2 *)dwclass)->C(0);
}

void MyClass1::B (void) {
    MyClass2 *myclass= (MyClass2 *)dwclass;
    delete myclass;
}

EDIT Thats a very little part of the original code. The CSRecodset class is only a casting class of CXdbRecordset, where all the real code is. Doing so I can let the user take benefit of what I wrote without loosing my rights. I do not pretend to demonstrate that my database engine is professional but it really works.

//-------------------------------------
class CSRecordSet : public CSObject
//-------------------------------------
{
public:
    CSRecordSet();
    virtual ~CSRecordSet();
    // Constructor
    bool Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef);
    //Open, find, close
    int OpenRst(bool bReadBlanks=0,bool bCheckLastSql=0,bool bForceLoad=0,bool bMessage=1);     // for a given SQL
    int FindRecord(bool bNext);         // for a given SQL
    // TABLE must be ordered by the same fields that will be seek
    bool SeekRecord(int nFieldIndex, char *key, int length=0);  // CRT bsearch
    bool SeekRecord(int nFieldIndex, long key);
    bool SeekRecord(int nFieldIndex, double key, int decimals);
    bool SeekRecord(XSEK *SEK);
    bool DeleteRecord(void);
    bool Close(void);
    // Record Position:
    bool IsEOF(void);           // pointer out of bound
    bool IsLAST(void);          // TRUE if last record
    bool IsBOF(void);           // pointer out of bound
    bool IsOpen(void);
    bool Move(long lRows);      // returns FALSE if out of bound
    void MoveNextNotEof(void);  // eof is tested
    void MoveNext(void);        // eof is not tested
    void MovePrev(void);        // bof is tested
    void MoveLast(void);
    void MoveFirst(void);
    void SetAbsolutePosition(long lRows);
    long GetAbsolutePosition(void);
    void GoToLast(void); // Restore position after a Filter
    // Table info
    long GetRecordCount(void);
    int GetRstTableNumber(void);
    int GetRecordLength(void); //includes stamp (sizeof char)
    int GetTableType(void);
    // Field info
    int GetFieldCount(void);
    void GetFieldName(int nFieldIndex, char *pbuffer);
    int GetFieldIndex(const char *sFieldName);
    int GetFieldSize(int nFieldIndex);
    int GetFieldDGSize(int nFieldIndex); // String size (i.e. dg_Boolean)
    long GetRecordID(void);
    int GetStandardFieldCount(void);
    bool IsMemoFileTable(void);
    bool IsNumberField(int nFieldIndex);
    int GetFieldType(int nFieldIndex);
    // Read Field value
    bool GetFieldValue(int nFieldIndex, XdbVar& var);
    bool GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer);
    char *GetMemoField(int nMemoFieldIndex, char *pbuffer, int buf_size);
    bool GetBinaryField(unsigned char *buffer,long *buf_size);
    // Write Field value
    void Edit(void); // required
    bool SetFieldValue(int nFieldIndex, XdbVar& var);
    bool SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer);
    bool Update(void); // required
    // pointer to the same lpSql
    LPXSQL GetSQL(void);
};

//---------------------------------------------------
CSRecordSet::CSRecordSet(){
//---------------------------------------------------
    pClass |= (CS_bAttach);
}
CSRecordSet::~CSRecordSet(){
    if(pObject) delete (CXdbRecordset*)pObject;
}
bool CSRecordSet::Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef){
    CXdbQueryDef *qr=(CXdbQueryDef*)pQueryDef->GetObject();
    CXdbTables *db=(CXdbTables*)pDataBase->GetObject();
    CXdbRecordset *rst = new CXdbRecordset(db,qr);
    if(rst==NULL) return 0;
    pObject = (unsigned long) rst;
    return 1;
}
bool CSRecordSet::Close(void){
    return ((CXdbRecordset*)pObject)->Close();
}
int CSRecordSet::OpenRst(bool bReadBlanks,bool bCheckLastSql,bool bForceLoad, bool bMessage){
    unsigned long dw=0L;
    if(bReadBlanks) dw|=SQL_bReadBlanks;
    if(bCheckLastSql) dw|=SQL_bCheckLastSql;
    if(bMessage) dw|=SQL_bRstMessage;
    if(bForceLoad) dw|=SQL_bForceLoad;

    return ((CXdbRecordset*)pObject)->OpenEx(dw);
}
int CSRecordSet::FindRecord(bool bNext){
    return ((CXdbRecordset*)pObject)->FindRecordEx(bNext);
}
bool CSRecordSet::DeleteRecord(void){
    return ((CXdbRecordset*)pObject)->DeleteEx();
}
bool CSRecordSet::IsEOF(void){
    return ((CXdbRecordset*)pObject)->IsEOF();
}
bool CSRecordSet::IsLAST(void){
    return ((CXdbRecordset*)pObject)->IsLAST();
}
bool CSRecordSet::IsBOF(void){
    return ((CXdbRecordset*)pObject)->IsBOF();
}
bool CSRecordSet::IsOpen(void){
    return ((CXdbRecordset*)pObject)->IsOpen();
}
bool CSRecordSet::Move(long lRows){
    return ((CXdbRecordset*)pObject)->MoveEx(lRows);
}
void CSRecordSet::MoveNextNotEof(void){
    ((CXdbRecordset*)pObject)->MoveNextNotEof();
}
void CSRecordSet::MoveNext(void){
    ((CXdbRecordset*)pObject)->MoveNext();
}
void CSRecordSet::MovePrev(void){
    ((CXdbRecordset*)pObject)->MovePrev();
}
void CSRecordSet::MoveLast(void){
    ((CXdbRecordset*)pObject)->MoveLast();
}
void CSRecordSet::MoveFirst(void){
    ((CXdbRecordset*)pObject)->MoveFirst();
}
void CSRecordSet::SetAbsolutePosition(long lRows){
    ((CXdbRecordset*)pObject)->SetAbsolutePosition(lRows);
}
long CSRecordSet::GetAbsolutePosition(void){
    return ((CXdbRecordset*)pObject)->m_AbsolutePosition;
}
long CSRecordSet::GetRecordCount(void){
    return ((CXdbRecordset*)pObject)->GetRecordCount();
}
int CSRecordSet::GetFieldCount(void){
    return ((CXdbRecordset*)pObject)->GetFieldCount();
}
int CSRecordSet::GetRstTableNumber(void){
    return ((CXdbRecordset*)pObject)->GetRstTableNumber();
}
void CSRecordSet::GetFieldName(int nFieldIndex, char *pbuffer){
    ((CXdbRecordset*)pObject)->GetFieldName(nFieldIndex,pbuffer);
}
int CSRecordSet::GetFieldIndex(const char *sFieldName){
    return ((CXdbRecordset*)pObject)->GetFieldIndex(sFieldName);
}
bool CSRecordSet::IsMemoFileTable(void){
    return ((CXdbRecordset*)pObject)->IsMemoFileTable();
}
bool CSRecordSet::IsNumberField(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->IsNumberField(nFieldIndex);
}
bool CSRecordSet::GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer){
    return ((CXdbRecordset*)pObject)->GetFieldValueIntoBuffer(nFieldIndex,pbuffer);
}
void CSRecordSet::Edit(void){
    ((CXdbRecordset*)pObject)->Edit();
}
bool CSRecordSet::Update(void){
    return ((CXdbRecordset*)pObject)->Update();
}
bool CSRecordSet::SetFieldValue(int nFieldIndex, XdbVar& var){
    return ((CXdbRecordset*)pObject)->SetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer){
    return ((CXdbRecordset*)pObject)->SetFieldValueFromBuffer(nFieldIndex,pbuffer);
}
bool CSRecordSet::GetFieldValue(int nFieldIndex, XdbVar& var){
    return ((CXdbRecordset*)pObject)->GetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SeekRecord(XSEK *SEK){
    return ((CXdbRecordset*)pObject)->TableSeek(SEK);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,char *key, int length){
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,key,length);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,long i){
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,i);
}
bool CSRecordSet::SeekRecord(int nFieldIndex, double d, int decimals)
{
    return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,d,decimals);
}
int CSRecordSet::GetRecordLength(void){
    return ((CXdbRecordset*)pObject)->GetRecordLength();
}
char *CSRecordSet::GetMemoField(int nMemoFieldIndex,char *pbuffer, int BUFFER_SIZE){
    return ((CXdbRecordset*)pObject)->GetMemoField(nMemoFieldIndex,pbuffer,BUFFER_SIZE);
}
bool CSRecordSet::GetBinaryField(unsigned char *buffer,long *buf_size){
    return ((CXdbRecordset*)pObject)->GetBinaryField(buffer,buf_size);
}
LPXSQL CSRecordSet::GetSQL(void){
    return ((CXdbRecordset*)pObject)->GetSQL();
}
void CSRecordSet::GoToLast(void){
    ((CXdbRecordset*)pObject)->GoToLast();
}
long CSRecordSet::GetRecordID(void){
    return ((CXdbRecordset*)pObject)->GetRecordID();
}
int CSRecordSet::GetStandardFieldCount(void){
    return ((CXdbRecordset*)pObject)->GetStandardFieldCount();
}
int CSRecordSet::GetTableType(void){
    return ((CXdbRecordset*)pObject)->GetTableType();
}
int CSRecordSet::GetFieldType(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldType(nFieldIndex);
}
int CSRecordSet::GetFieldDGSize(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldDGSize(nFieldIndex);
}
int CSRecordSet::GetFieldSize(int nFieldIndex){
    return ((CXdbRecordset*)pObject)->GetFieldSize(nFieldIndex);
}

EDIT: requested by DeadMG:

void nimportequoidumomentquecaroule(void) {

    short i = -4;
    unsigned short j=(unsigned short)i;

}


问:
Can unit testing software be used to unit test itself?
QUnit advertises itself on its web page like this:

...capable of testing any generic JavaScript code, including itself!

Can you really use unit testing software to test itself? Wouldn't defects in the software mean that the results are unreliable?

答:
You are correct, defects in the software do mean that the results are unreliable. However, there is a way to work around it, and build a reliable suite of tests.

The idea is to build a small testing harness that tests the very basic "core" functionality of each component of the testing system (usually, it consists of at least a framework and a runner). If testing framework is flexible enough, you should be able to plug that harness straight into your system, for example, by implementing an interface or by providing a required set of methods in the implementation of your harness.

The rest of the functionality should be tested relying solely on the "core" functionality, which is already tested using the harness. If you take care of using only the functionality from the "core" to test the non-core functionality, you would have a set of tests that you can trust.

ContentLicense: CC BY-SA 3.0


问:
Naming convention for main arguments
I recently started using arguments in my main program (here written in C++ but could be any programming language)

#include <iostream>

int main(int argn, char* argv[]) {
    // do stuff depending on argv[1], argv[2], etc.
}
```

For now I am using mostly random naming conventions like -t for testing, -d for debugging, -l for printing logs e.g. There is no need for adding -, it is just that most shell parameters are named that way. I also use -- for second parameters.

Is there any established naming conventions for main arguments ?

答:
Gnu Standards  and GNU long argument names

Microsoft's suggestions

Title: Naming convention for main arguments


问:
Unit Testing: "It's a code smell if you're refactoring and there are no collaborators"?
I'm reading The Art of Unit Testing by Roy Osherove. I'm at section 7.2 Writing maintainable tests where the author has this note about code smell:

NOTE: When you refactor internal state to be visible to an outside
  test, could it be considered a code smell (a sign that something might
  be wrong in the code's design or logic)? It's not a code smell when
  you're refactoring to expose collaborators. It's a code smell if
  you're refactoring and there are no collaborators (so you don't need
  to stub or mock anything).

EDIT: What the author means by "collaborators" is dependencies. Some of his examples for dependencies are classes that access a database or that access the OS's file system. Here is where he defines stub and begins to use the word collaborator:

A stub is a controllable replacement for an existing dependency (or
  collaborator) in the system.

The author doesn't have an example of this code smell and I'm having trouble understanding/picturing what this would look like. Can someone explain this a little more and perhaps provide a concrete example?

答:
I think this is what the author is getting at.

In my code sample, I have a timing window that takes an output quantity plus a start and stop time.  The intent is to draw an output window over a 24 hour timespan.  A wrinkle is added when start time is greater than stop time because that's a timing window that spans midnight.

You can write unit tests that fully exercise the object without exposing the private variables.  Those private bools and timespans are the collaborators he's referring to when exposing the internals for unit testing.  According to the book, exposing those internals would NOT be a code smell since they are collaborators.

Exposing the double output would be a code smell since it's not a collaborator - it's an element explicitly hidden by the class itself that has conditional logic within GetOutput to determine what should be returned.

Digging into the bools / timespans would make the unit tests more comprehensive.  He says this is good.

Digging into the double output would require additional logic in your unit test that mirrored what GetOutput was doing.  This would be the code smell he's referring to.

```
public class TimeWindow
{
  private bool isConst;
  private bool spansMidnight;
  private TimeSpan start1;
  private TimeSpan stop1;
  private TimeSpan start2;
  private TimeSpan stop2;
  private double output;

  public TimeWindow( double out, TimeSpan start, TimeSpan stop)
  {
    output = out;

    if( start == stop )
      isConst = true;
    else if( start > stop )
    {
      spansMidnight = true;
      start1 = midnight;
      stop1 = stop;
      start2 = start;
      stop2 = midnight;
    }
    else
    {
      start1 = start;
      stop1 = stop;
    }
  }

  public double GetOutput( TimeSpan time )
  {
    // some logic here on what / how to return
    ...
    return output;
  }

}
```

Body:
I think this is what the author is getting at.

In my code sample, I have a timing window that takes an output quantity plus a start and stop time.  The intent is to draw an output window over a 24 hour timespan.  A wrinkle is added when start time is greater than stop time because that's a timing window that spans midnight.

You can write unit tests that fully exercise the object without exposing the private variables.  Those private bools and timespans are the collaborators he's referring to when exposing the internals for unit testing.  According to the book, exposing those internals would NOT be a code smell since they are collaborators.

Exposing the double output would be a code smell since it's not a collaborator - it's an element explicitly hidden by the class itself that has conditional logic within GetOutput to determine what should be returned.

Digging into the bools / timespans would make the unit tests more comprehensive.  He says this is good.

Digging into the double output would require additional logic in your unit test that mirrored what GetOutput was doing.  This would be the code smell he's referring to.

public class TimeWindow
{
  private bool isConst;
  private bool spansMidnight;
  private TimeSpan start1;
  private TimeSpan stop1;
  private TimeSpan start2;
  private TimeSpan stop2;
  private double output;

  public TimeWindow( double out, TimeSpan start, TimeSpan stop)
  {
    output = out;

    if( start == stop )
      isConst = true;
    else if( start > stop )
    {
      spansMidnight = true;
      start1 = midnight;
      stop1 = stop;
      start2 = start;
      stop2 = midnight;
    }
    else
    {
      start1 = start;
      stop1 = stop;
    }
  }

  public double GetOutput( TimeSpan time )
  {
    // some logic here on what / how to return
    ...
    return output;
  }

}


答:
Let's say we have a domain class, and this domain class has direct knowledge of the persistence layer using a Repository, which it uses in order to expose an instance-level "Save" method that objects working on the domain class can call to persist changes made without needing knowledge of the mechanism (whether this is "good" design is a discussion for another day). Refactoring the class to expose this Repository as a property and/or constructor argument, thus allowing a mocked Repository to be passed that can ensure the proper call is made, is typically a good thing not only for testing but general maintainability.

Now, this being a domain class, it has state data. Let's assume for a moment that one of the stateful properties has a backing field, and the property accessors test that a new input is valid based on the current one (maybe the new value can never be less than the old one). You need to test this validation, but you find that doing so requires access to the backing field to set an initial value that you'll then try to overwrite. This should be a red flag; if the test needs access to the backing field (which is an implementation detail; no consumer should ever have to know it's there) in order to get the object into a consistent state for a test, then how would production code get a consistent object? If there is a method for production code to do the same thing your test does, then the test should probably mimic that way. If there isn't a valid way for production code to get the object into this state, then why are you testing this scenario?

Title: Unit Testing: "It's a code smell if you're refactoring and there are no collaborators"?

Body:
I'm reading The Art of Unit Testing by Roy Osherove. I'm at section 7.2 Writing maintainable tests where the author has this note about code smell:

NOTE: When you refactor internal state to be visible to an outside
  test, could it be considered a code smell (a sign that something might
  be wrong in the code's design or logic)? It's not a code smell when
  you're refactoring to expose collaborators. It's a code smell if
  you're refactoring and there are no collaborators (so you don't need
  to stub or mock anything).

EDIT: What the author means by "collaborators" is dependencies. Some of his examples for dependencies are classes that access a database or that access the OS's file system. Here is where he defines stub and begins to use the word collaborator:

A stub is a controllable replacement for an existing dependency (or
  collaborator) in the system.

The author doesn't have an example of this code smell and I'm having trouble understanding/picturing what this would look like. Can someone explain this a little more and perhaps provide a concrete example?


答: Kent Beck's book "Test Driven Development By Example" does precisely this: as an example of TDD he bootstraps a test framework that right from the beginning is used to develop itself.</p>

Title: Can unit testing software be used to unit test itself?

Body:
QUnit advertises itself on its web page like this:

...capable of testing any generic JavaScript code, including itself!

Can you really use unit testing software to test itself? Wouldn't defects in the software mean that the results are unreliable?


问:
Effective ways to make your OSS project popular?
After writing a few (relatively obscure) OSS frameworks, I've learned the hard way that writing a good framework isn't enough--there has to be some time spent marketing your framework as much as the time you spend coding it. So here's my question: What are some effective ways for making your OSS project become well-known? Aside from blogging, how do I gain the most market attention for my code with the least amount of effort as humanly possible?

(EDIT: I'm a lazy programmer and I hate documentation, but I'm biting the bullet. I want to be famous)

答: Write it and they will come. In the OSS 'market' it is generally quality that rises to the top. It is thankfully free of bluster and hot air.</p>

ContentLicense: CC BY-SA 2.5


问:
Why can't there be an "universal" programming language that serves all purposes?
why not combine the best features of the all existent programming languages and fit it in a universal programming language?</p>

答:
With all that is written so far, it is hard to add much new rationale, but I will throw in a few.

Evolution : It is not just biological systems that are introduced, mutate and undergo a survival-of-the-fittest competition for resources and a niche to call their own.  The competition is good and pushes things forward.

Maturity : We have been making computer languages for probably less than a century.  We can't have the answer yet because we don't even know all the questions yet.

Separate genesis : Not sure the right word for this, but in the world their are many writing systems that started in many geographic regions.  Think about Cuneiform that was dictated in part by the demands of carving into clay tablets.  Think about Sanskrit, the Greek, Hebrew, Roman, Arabic alphabets.  Hieroglyphics, the Chinese method of beautiful writing with 6000+ symbols that is shared in many east Asian countries.  Think of more modern mixed alphabets with phonetic basis like Cyrillic, Katakana, and Hirigana.  I am not  a linguist so don't flame the inaccuracies too harshly, but when cultures worldwide need something, they will create it and make it their own out of necessity.  Computer languages came along when there was a lot of worldwide communication and like the Imperial and Metric systems, came from places with powerful idea leadership.  But programming languages serve many different cultures (some of them corporate cultures), so they reflect the people who made them.  Computer languages come with cultural legacies that shaped their design and use.  In the OS kernel culture, C and C++ are unlikely to be soon deprecated for Java (or the other way around) because they permit native code generation, close / efficient coupling with hardware for creating hardware abstraction layers, and have a sizable installed based.

Design of Design : Programming languages come about using different organizational paradigms.  COBOL and Ada were from committees that were part of DOD which had a lot of hierarchy.  If I recall correctly C, C++, Java, and probably many others came from one or a small number of designers.  Fred Brooks compares the results of the committee vs. the visionary based approaches in his paper, the Design of Design (http://www.youtube.com/watch?v=pC-DlX-PaF4).  If we sat down today to either select a Da Vinci or a committee to define the universal programming language, would we know who or what by what method it should be architected?


问:
How should I deal with Time Zones in a .NET WCF application?
Our company runs a SaaS application where users log in from across the world (although mostly in the US).  We store all our time relevant information as UTC, but we need to display times using local time.  The application is web based, and we would like to "auto-detect" the user's Time Zone by using javascript to determine their UTC offsets during various times of the year.  The user's offset info would be passed to our server in their first request and the server will look up all the Time Zones that it knows about and see which valid time zones match.

I'd like to use the built in TimeZoneInfo object, but I understand that

```<code>TimeZoneInfo.GetSystemTimeZones();
</code>```

relies on the server's registry settings.  We currently have 18 load balanced web servers that host our WCF service layer, and I believe our TechOps team is vigilant in making sure that all servers are patched with the same service pack at all times.

I also need to pay special attention to the various US Time Zones, specifically Pacific, Mountain, Central and Eastern.  Can I assume that the string based Id field will not change anytime soon?  For example, if I call

```<code>TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")
</code>```

I want the appropriate TimeZoneInfo object to be returned.

So a few questions:

What is the best way to deal with time zones, especially when it comes to the changing rules (US time zone rules changed in 2006) and determining offsets.  Should I be trying something else?  Keep in mind that the product team doesn't want the user to have to select their time zone and they are fine with time zones being inaccurately reported under certain  conditions (e.g. if the user is in Mexico, it is ok to be reported as "Pacific Standard Time" instead of the more accurate "Pacific Standard Time (Mexico)".

If I assume that all of our load balanced web servers are always running the same OS version and patch level, can I assume that I will get consistent results?

Are there any other things I need to consider?

答:
I think you're on the right track with using the built in TimeZoneInfo class.  The ID should never change, but the name will (I learned that lesson the hard way when several changed between xp and vista).  I have used a virtually identical approach (UTC only at the service and db layers, local time on the web server & client) and it worked just fine.

One thing I suggest is to wrap the various TimeZoneInfo methods you intend to use with an interface ITimeZoneConverter or something of that nature, that way if you need to change your implementation later, it should be easier to do.

Random Annoyance:  The .Net TimeZoneInfo class can't give you an abbreviation given a timezone.  IE: No "EST" for "Eastern Standard Time", so if you need that, plan on having a lookup into some sort of resource file or table for that.

Javascript won't actually be able to tell you the timezone, just the timezone offset from UTC.   It's a subtle difference, and in your case it sounds like it won't matter, but it's something to keep in mind when looking at what timezones get assigned to your users.

I have seen some JS libraries such as this one which attempt to guess the timezone on the client side based on offset and most populated timezones.  It is an interesting approach, but I don't know how well it would work in production.

Finally, one thing that bit me in the past was that JSON doesn't actually specify anything about how to format datetimes. (related reading)  If you're doing a lot of ajax/async requests and intend to convert back and forth between utc & local times, this can be painful.  Make sure you write some good common parsing/offsetting functions and make sure everyone on your team is aware of them and doesn't re-invent the wheel every time when dealing with these issues.


答:
Maybe a little different slant on all this:

What is a language? To be ridiculously simple, it's vocabulary, syntax, and semantics.

What's the first thing you do with a programming language?

You define things - classes, variables, methods - you extend the vocabulary and the semantics.

Why? So now you can say things in it you could not say before.

Like it or not, you've made a new special-purpose language.

IMHO, the thing to look for in a general-purpose language is if it makes it easy to create special-purpose languages.

Title: Why can't there be an "universal" programming language that serves all purposes?

Body: why not combine the best features of the all existent programming languages and fit it in a universal programming language?</p>


问:
What are the pros and cons of a language using whitespace vs. {}'s to indicate scope?
There seems to be a conflict over whether its better to use whitespace or tokens like brackets to indicate scope. I've seen many praise python's solution to the inconsistent indentation problem, but many disagree:

Any language that has whitespace as tokens needs to die.

posted later on the same answer:

I was sortof anti-whitespace-as-tokens, until I actually tried it. It probably helped that my personal white-space layout pretty much matches what everyone in python-land uses. Perhaps it's that I am a bit minimalist, but if you're going to indent anyways, why bother with the {}s?

I can see some clear arguments for each side:

using whitespace:

helps reduce inconsistent indentation in code

clears the screen by replace visible tokens with whitespace to serve the same purpose

using tokens:

much easier to cut and paste code to different levels (you don't have to fix the
indentation)

more consistent. Some text editors display whitespace differently.

more popular currently.

Are there any points I missed? Which do you prefer? Any words of wisdom after having worked with one or the other for a long time?

PS. I hate it when languages don't use the same token for each control structure. VB is really annoying with its End If and End While statements, most other languages just use {}'s for everything. But maybe that's a topic for a different question...

答:
I think a lot of us programmers (myself included) have a tendency to "logicalize" every decision.  That's fine, but not every question has a logical answer.  For instance, I doubt that chefs post questions on chefoverflow (if such a thing exists) asking for the pros and cons of apple pie vs cherry pie.  It's a question of which you like better.

With that in mind, I think the simplest answer is to say "Some people like braces, some people like whitespace" and leave it at that.


答: No you can't test software with itself, at least not in a way that would be acceptable in an audit situation. Independent verification has become a well established norm because it is far less likely that two different X(people, frameworks, tools) will both make the same mistake/ have the same bugs. This doesn't guarantee that whatever you test is actually correct, but it does mean there is a lesser chance of incorrectly passing any test. Testing something with itself can't actually increase your confidence that it works correctly, but it can be useful as a quick and dirty check to reduce the time it takes to receive feedback.</p>


问:
When to prefer a generalized solution over solving specific cases
In programming we're often faced with a choice: cover each conceivable use case individually, or solve the general problem:

Its obvious that solving the immediate problem is faster, however creating a generalized solution will save time in the future.

How do I know when it's best to try and cover a finite list of cases, or make a generic system to cover all possibilities?

答:
One, two, many!

On the second case you should be thinking on generalization. On being asked for the third you should supply it from the generalized code and use the first and second case previously solved individually as test cases.


问:
Which timezone is used for permalinks of posts
I wanted to add timezone support to my blog app but got stuck with a design problem.

Every post has a published_on field which stores the publication date in a timezone aware format (UTC converted to user's timezone). So far so good. But the permalink of a post is created from the publication date as well. It has the format: /year/month/day/slug.

This of course is not timezone aware and must be the same for all users around the world. So I have to define a timezone to use for the permalink. There are three options which make sense:

The author's timezone

UTC

The default timezone of the server.

Which would be the most appropriate?

答:
We had the same problem in our project and we persisted all the time in database as UTC.

The UTC time is converted to local timezone of the user when accessing / reading the data. This simplified our entire design.


答:
I'd go with UTC. It has several advantages:

It's universal and doesn't change with daylight saving time.

It won't change if your server changes timezone.

It won't change if authors change timezone.

There are standard conversions between UTC and local time zones.

Despite the problems it sometimes causes (confusion over the "day") it can be explained and is consistent.

Title: Which timezone is used for permalinks of posts

Body:
I wanted to add timezone support to my blog app but got stuck with a design problem.

Every post has a published_on field which stores the publication date in a timezone aware format (UTC converted to user's timezone). So far so good. But the permalink of a post is created from the publication date as well. It has the format: /year/month/day/slug.

This of course is not timezone aware and must be the same for all users around the world. So I have to define a timezone to use for the permalink. There are three options which make sense:

The author's timezone

UTC

The default timezone of the server.

Which would be the most appropriate?


问:
How should UI layer pass user input to BL layer?
I'm building an n-tier application, I have UI, BL, DAL & Entities (built from POCO) projects. (All projects have a reference to the Entities).

My question is - how should I pass user input from the UI to the BL, as a bunch of strings passed to the BL method and the BL will build the object from the parameters, or should I build the objects inside the UI submit_function and send objects as parameters?

EDIT: I wrote n-tier application, but what I actually meant was just layers.

答:
In an ideal (service oriented multi-tier) world UI should communicate to a business layer through data contracts and a service facade.  The UI should not need to know anything about the actual business layer or the entities and methods the business layer works with.  So a UI and service facade would share a data contract definition (these can be simple container classes or XSD's).  The UI would call methods on an exposed service facade using the data contract to pass the business data back and forth.  It's then up to the service facade to translate the data contract into BL entities and call the BL methods necessary to perform the service.

Why?

This creates a clean interface between your UI and BL based on purposely and explicitly exposed services and contracts.  Changes in one layer do not need to impact another.

It aids in creation of automated unit tests.  You can even test the UI with mock implementations of the service facade.

It pushes for a more service focused approach.  It is services that are exposed rather than a series of individual method calls.  "Hopefully" limiting the number of calls between a UI and BL.


问:
Filtering lists in an Android App offline or online?
I have an android app that fetches a list of about 100 Items.

Trying to get the server load down, I've built a filtering feature that

does everything offline, so basically instead of calling the server (and thus a MySQL query every call)

It filters on its own.

However I've noticed the app tends to lag (while the only change is the offline filtering).

Is the processing of relatively big object-lists something that should be done offline or should I live the load on the server ?

答:
You cannot know where your problem is unless you profile. Is the lag in the data connection (100 records over mobile might be a slow, the processing at the app, or is the server takling longer to get the data?

If a 100 item list is bogging down the server, I think you might have bigger problems to solve than off loading the filtering work to the devices will help with...... Did you profile the server before you optimized? Perhaps the server is having problems with Bandwidth to the devices - this would make you optimized code have less performance.

As an aside to the original question, I find it hard to believe that there benefit to anyone having a typical Android device do the filtering. The server is sending way more data to the devices than needed, the devices are handling way more data than the need to, and way more data is being sent over the networks. If these are mobile networks, that are often slow, and in some countries, data is expensive.  In all countries when roaming, data charges are criminal.


问:
Is there any advantage to learning C first?
I've got a little bit of history with programming, having gotten my start with Visual Basic. I let it slide as a hobby from a little after VB6 up until just a year or so ago when I got on the iPhone bandwagon, when I decided to take up Objective-C programming.

I now have what I feel to be an intermediate level of knowledge on the language, but I can't help but feel that there's a substantial gap in where my knowledge is, given that there seems to be a substantial bit of the language I don't feel I understand.

Would I benefit from reviewing the underlying C structure, or would I be better served from continuing to practice solely in Objective-C whilst reviewing the documentation for various features?

Edit: Though I've accepted the first answer given, more insight is always appreciated from those with supplementary or opposing views.

答:
It depends on what you don't understand about Obj-C.  If you feel you have a good grip on the OO side, but struggle with things like pointers or array semantics, then by all means you want to explore the lower-level C side of things.  </p>

<p>If you're struggling with OO concepts or message passing or the runtime, then learning C won't help you at all.  </p>

Body:
It depends on what you don't understand about Obj-C.  If you feel you have a good grip on the OO side, but struggle with things like pointers or array semantics, then by all means you want to explore the lower-level C side of things.

If you're struggling with OO concepts or message passing or the runtime, then learning C won't help you at all.


答:
Here's how I typically build my n-tier applications, in this case, let's use an MVC web application project.

A class library, typically called: ProjectFoo.Domain:

Here's where I create my abstract repositories for accessing data. For example:

```<code>public interface IAccountRepository
{
    IEnumerable<Account> FindAll();
}
</code>```

I also create my concrete implementations here, one accesses the real database, the other just returns mock information:

```<code>public class DbAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        DbConnector db = new DbConnector();
        return db.Accounts;
    }
}

public class MockAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        return new List<Account>(){
            new Account { Name = "Sergio", Age = 22 },
            new Account { Name = "Brad", Age = 42 },
            new Account { Name = "Chelios", Age = 32 },
        }
    }
}
</code>```

Next, in my UI project, typically called ProjectFoo.WebUI:

Inside a controller I use dependency injection to sort out what implementation I'm working against:

```<code>public class AccountController
{
    IAccountRepository _accountRepository = new IAccountRepository();

    public AccountController(IAccountRepository accountRepository)
    {
        _accountRepository = accountRepository;
    }

    public ActionResult Index()
    {
        // Magic! We don't need to know what exactly we're working against.
        var accounts = accountRepository.FindAll();
    }
}
</code>```

Now onto your question, How to pass user input from the UI to the BL?.

I have my interface written like this:

```<code>public class DbAccountRepository : IAccountRepository
{
    // Notice this is the entity object type.
    public void AddAccount(Account account)
    {
        db.AddToAccounts(account);
        db.SaveChanges();
    }
}
</code>```

Grab user input, shape it, validate it, fit it inside a simple POCO object - once you're sure it's sanitized and functioning correctly, use something like AutoMapper to map to your entity object and pass fully loaded object along the chain towards your repository.

If you have any question or don't quite understand something let me know.

Title: How should UI layer pass user input to BL layer?

Body:
I'm building an n-tier application, I have UI, BL, DAL & Entities (built from POCO) projects. (All projects have a reference to the Entities).

My question is - how should I pass user input from the UI to the BL, as a bunch of strings passed to the BL method and the BL will build the object from the parameters, or should I build the objects inside the UI submit_function and send objects as parameters?

EDIT: I wrote n-tier application, but what I actually meant was just layers.

Body:
Here's how I typically build my n-tier applications, in this case, let's use an MVC web application project.

A class library, typically called: ProjectFoo.Domain:

Here's where I create my abstract repositories for accessing data. For example:

public interface IAccountRepository
{
    IEnumerable<Account> FindAll();
}

I also create my concrete implementations here, one accesses the real database, the other just returns mock information:

public class DbAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        DbConnector db = new DbConnector();
        return db.Accounts;
    }
}

public class MockAccountRepository : IAccountRepository
{
    public IEnumerable<Account> FindAll()
    {
        return new List<Account>(){
            new Account { Name = "Sergio", Age = 22 },
            new Account { Name = "Brad", Age = 42 },
            new Account { Name = "Chelios", Age = 32 },
        }
    }
}

Next, in my UI project, typically called ProjectFoo.WebUI:

Inside a controller I use dependency injection to sort out what implementation I'm working against:

public class AccountController
{
    IAccountRepository _accountRepository = new IAccountRepository();

    public AccountController(IAccountRepository accountRepository)
    {
        _accountRepository = accountRepository;
    }

    public ActionResult Index()
    {
        // Magic! We don't need to know what exactly we're working against.
        var accounts = accountRepository.FindAll();
    }
}

Now onto your question, How to pass user input from the UI to the BL?.

I have my interface written like this:

public class DbAccountRepository : IAccountRepository
{
    // Notice this is the entity object type.
    public void AddAccount(Account account)
    {
        db.AddToAccounts(account);
        db.SaveChanges();
    }
}

Grab user input, shape it, validate it, fit it inside a simple POCO object - once you're sure it's sanitized and functioning correctly, use something like AutoMapper to map to your entity object and pass fully loaded object along the chain towards your repository.

If you have any question or don't quite understand something let me know.


问:
How to share methods and properties between custom web controls
I'm building some custom web controls in .NET using C#.  The controls inherit from the standard web controls, and add additional properties and functionality (e.g. I'm creating an 'extendedTextBox' and I'm adding a 'required' property, which if set to 'true' will add a .NET required field validator to the control automatically.

I'm doing this for a number of web controls (e.g. radioButtonList, textArea).  They share some common properties and methods, for example I have an AddRequiredFieldValidator method that uses some of the extended properties I've added.  I'd like to share the common properties and methods.  I've tried adding the methods to a separate class as extension methods for a web control.  To achieve this I've implemented an interface that defines the additional shared properties, and am using it like this:

```<code>public interface IExtendendControl
{
    string RequiredMessage { get; set; }
    string ValidatorCssClass { get; set; }
    bool ClientScript { get; set; }
    RequiredFieldValidator rfv { get; set; }
}

public static class ExtendedControlExtensions : IExtendendControl
{
    public static void AddRequiredFieldValidator(this IExtendendControl control)
    {
        control.rfv = new RequiredFieldValidator();
        control.rfv.ErrorMessage = control.RequiredMessage;
        ConfigureAndAddValidator(control, control.rfv);
    }

    public static void ConfigureAndAddValidator(this IExtendendControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}
</code>```

Trouble is that the 'ConfigureAndAddValidator' method now doesn't know anything about the 'ID' or 'ClientScript' properties of the control since 'IExtendedControl' only defines the custom properties, not the standard properties of a web control.  So I tried adding a base class that inherits from WebControl and implements the interface, like this:

```<code>public interface IExtendendControl
{
    string RequiredMessage { get; set; }
    string ValidatorCssClass { get; set; }
    bool ClientScript { get; set; }
    RequiredFieldValidator rfv { get; set; }
}

public class BaseExtendedControl : WebControl, IExtendendControl
{
    public string RequiredMessage { get; set; }
    public string ValidatorCssClass { get; set; }
    public bool ClientScript
    {
        get
        { return ClientScript = true; }
        set { }
    }
    public RequiredFieldValidator rfv
    {
        get
        { return rfv = new RequiredFieldValidator(); }
        set { }
    }
}

public static class ExtendedControlHelper : IExtendendControl
{
    public static void AddRequiredFieldValidator(this BaseExtendedControl control)
    {
        BaseExtendedControl extendedControl = (BaseExtendedControl)control;
        extendedControl.rfv = new RequiredFieldValidator();
        extendedControl.rfv.ErrorMessage = extendedControl.RequiredMessage;
        ConfigureAndAddValidator(control, extendedControl.rfv);
    }

    public static void ConfigureAndAddValidator(this BaseExtendedControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}
</code>```

The trouble now is that in my extendedTextBox class I can't cast my extendedTextBox as a 'BaseExtendedControl' to use the extension methods, as the extendedTextBox inherits from the standard TextBox class like this:

```<code>public class ExtendedTextBox : TextBox, IExtendendControl
</code>```

so there's no common base to cast ExtendedTextBox as 'BaseExtendedControl' as it doesn't inherit from it.  I also can't just pass the extended web control objects as a parameter into the shared methods as the extended controls are of different types (e.g. they inherit from TextBox, RadioButtonList and so on).  If I specify the expected type being passed into 'standard' methods as 'WebControl' it doesn't work as the extended controls have the additional properties.

As I can't use true multiple inheritance in C#, how would I design this to be able to share the methods and properties?

答:
I'm not sure this entire approach adds much over just adding a validator when you want one, since you'll end up with more and more controls for every type of validation.

But if you really want to do something like this, one way you can do it is with a generic control that inherits from the supplied control:

```<code>public class RequiredField<ControlType>: ControlType where ControlType:WebControl
{
    //In here you can access all of the functionality of a WebControl,
    //as well as add additional properties
}
</code>```

Body:
I'm not sure this entire approach adds much over just adding a validator when you want one, since you'll end up with more and more controls for every type of validation.

But if you really want to do something like this, one way you can do it is with a generic control that inherits from the supplied control:

public class RequiredField<ControlType>: ControlType where ControlType:WebControl
{
    //In here you can access all of the functionality of a WebControl,
    //as well as add additional properties
}


答:
As I can't use true multiple inheritance in C#, how would I design
  this to be able to share the methods and properties?

This is the right way to share the methods and properties. But:

The trouble now is that in my extendedTextBox class I can't cast my
  extendedTextBox as a 'BaseExtendedControl' to use the extension
  methods, as the extendedTextBox inherits from the standard TextBox
  class like this:

```<code>public class ExtendedTextBox : TextBox, IExtendedControl
</code>```

so there's no common base to cast ExtendedTextBox as
  'BaseExtendedControl' as it doesn't inherit from it.

Yes, you're right there is no common class, but you can solve the problem by casting to the IExtentedControl interface which is common to your classes and contains the methods that you need. So what about:

```<code>public static class ExtendedControlHelper
{
    public static void AddRequiredFieldValidator(this IExtendedControl control)
    {
        control.rfv = new RequiredFieldValidator();
        control.rfv.ErrorMessage = control.RequiredMessage;
        ConfigureAndAddValidator(control, control.rfv);
    }

    public static void ConfigureAndAddValidator(this IExtendedControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}
</code>```

I don't think you need to implement the IExtendedControl interface in the ExtendedControlHelper class. Moreover I corrected the grammar of the interface name from IExtendendControl to IExtendedControl.

EDIT :

Another solution could be to use the dynamic keyword. The dynamic keyword is like object but the type is checked at run time instead of compile time:

```<code>public static class ExtendedControlHelper
{
    public static void AddRequiredFieldValidator(this dynamic control)
    {
        //...
    }

    public static void ConfigureAndAddValidator(this dynamic control, BaseValidator validator)
    {
         //...
    }
}
</code>```

The dynamic type doesn't exist at run time because it's solved by the compiler, so if you write this: myExtendedTextBox.AddRequiredFieldValidator(); the method is solved as

```<code>//...
public static void AddRequiredFieldValidator(this ExtendedTextBox control)
{
    //...
}
</code>```

and so on. So the type can change continuously at run time.

For more informations give a look here.

Title: How to share methods and properties between custom web controls

Body:
I'm building some custom web controls in .NET using C#.  The controls inherit from the standard web controls, and add additional properties and functionality (e.g. I'm creating an 'extendedTextBox' and I'm adding a 'required' property, which if set to 'true' will add a .NET required field validator to the control automatically.

I'm doing this for a number of web controls (e.g. radioButtonList, textArea).  They share some common properties and methods, for example I have an AddRequiredFieldValidator method that uses some of the extended properties I've added.  I'd like to share the common properties and methods.  I've tried adding the methods to a separate class as extension methods for a web control.  To achieve this I've implemented an interface that defines the additional shared properties, and am using it like this:

```<code>public interface IExtendendControl
{
    string RequiredMessage { get; set; }
    string ValidatorCssClass { get; set; }
    bool ClientScript { get; set; }
    RequiredFieldValidator rfv { get; set; }
}

public static class ExtendedControlExtensions : IExtendendControl
{
    public static void AddRequiredFieldValidator(this IExtendendControl control)
    {
        control.rfv = new RequiredFieldValidator();
        control.rfv.ErrorMessage = control.RequiredMessage;
        ConfigureAndAddValidator(control, control.rfv);
    }

    public static void ConfigureAndAddValidator(this IExtendendControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}
</code>```

Trouble is that the 'ConfigureAndAddValidator' method now doesn't know anything about the 'ID' or 'ClientScript' properties of the control since 'IExtendedControl' only defines the custom properties, not the standard properties of a web control.  So I tried adding a base class that inherits from WebControl and implements the interface, like this:

```<code>public interface IExtendendControl
{
    string RequiredMessage { get; set; }
    string ValidatorCssClass { get; set; }
    bool ClientScript { get; set; }
    RequiredFieldValidator rfv { get; set; }
}

public class BaseExtendedControl : WebControl, IExtendendControl
{
    public string RequiredMessage { get; set; }
    public string ValidatorCssClass { get; set; }
    public bool ClientScript
    {
        get
        { return ClientScript = true; }
        set { }
    }
    public RequiredFieldValidator rfv
    {
        get
        { return rfv = new RequiredFieldValidator(); }
        set { }
    }
}

public static class ExtendedControlHelper : IExtendendControl
{
    public static void AddRequiredFieldValidator(this BaseExtendedControl control)
    {
        BaseExtendedControl extendedControl = (BaseExtendedControl)control;
        extendedControl.rfv = new RequiredFieldValidator();
        extendedControl.rfv.ErrorMessage = extendedControl.RequiredMessage;
        ConfigureAndAddValidator(control, extendedControl.rfv);
    }

    public static void ConfigureAndAddValidator(this BaseExtendedControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}
</code>```

The trouble now is that in my extendedTextBox class I can't cast my extendedTextBox as a 'BaseExtendedControl' to use the extension methods, as the extendedTextBox inherits from the standard TextBox class like this:

```<code>public class ExtendedTextBox : TextBox, IExtendendControl
</code>```

so there's no common base to cast ExtendedTextBox as 'BaseExtendedControl' as it doesn't inherit from it.  I also can't just pass the extended web control objects as a parameter into the shared methods as the extended controls are of different types (e.g. they inherit from TextBox, RadioButtonList and so on).  If I specify the expected type being passed into 'standard' methods as 'WebControl' it doesn't work as the extended controls have the additional properties.

As I can't use true multiple inheritance in C#, how would I design this to be able to share the methods and properties?

Body:
As I can't use true multiple inheritance in C#, how would I design
  this to be able to share the methods and properties?

This is the right way to share the methods and properties. But:

The trouble now is that in my extendedTextBox class I can't cast my
  extendedTextBox as a 'BaseExtendedControl' to use the extension
  methods, as the extendedTextBox inherits from the standard TextBox
  class like this:

public class ExtendedTextBox : TextBox, IExtendedControl

so there's no common base to cast ExtendedTextBox as
  'BaseExtendedControl' as it doesn't inherit from it.

Yes, you're right there is no common class, but you can solve the problem by casting to the IExtentedControl interface which is common to your classes and contains the methods that you need. So what about:

public static class ExtendedControlHelper
{
    public static void AddRequiredFieldValidator(this IExtendedControl control)
    {
        control.rfv = new RequiredFieldValidator();
        control.rfv.ErrorMessage = control.RequiredMessage;
        ConfigureAndAddValidator(control, control.rfv);
    }

    public static void ConfigureAndAddValidator(this IExtendedControl control, BaseValidator validator)
    {
        validator.ControlToValidate = control.ID;
        validator.Display = ValidatorDisplay.Dynamic;
        validator.CssClass = "validationMessage ";
        validator.CssClass += control.ValidatorCssClass;
        validator.EnableClientScript = control.ClientScript;
        control.Controls.Add(validator);
    }
}

I don't think you need to implement the IExtendedControl interface in the ExtendedControlHelper class. Moreover I corrected the grammar of the interface name from IExtendendControl to IExtendedControl.

EDIT :

Another solution could be to use the dynamic keyword. The dynamic keyword is like object but the type is checked at run time instead of compile time:

public static class ExtendedControlHelper
{
    public static void AddRequiredFieldValidator(this dynamic control)
    {
        //...
    }

    public static void ConfigureAndAddValidator(this dynamic control, BaseValidator validator)
    {
         //...
    }
}

The dynamic type doesn't exist at run time because it's solved by the compiler, so if you write this: myExtendedTextBox.AddRequiredFieldValidator(); the method is solved as

//...
public static void AddRequiredFieldValidator(this ExtendedTextBox control)
{
    //...
}

and so on. So the type can change continuously at run time.

For more informations give a look here.


答:
To build on the answers from dasblinkenlight and Paddy3118, if you don't have multiple cases to implement, then you don't need to generalize! The reason the XKCD cartoon is funny is that it lampoons premature generalization. Upon being asked to pass the salt, the unseen character immediately leaps to "developing a system to pass arbitrary condiments" when all the first character asked for was the salt. This is a good joke for developers, since I think we've all seen cases of premature generalization.

The principle opposed to premature generalization is YAGNI (You Ain't Gonna Need It). There are many materials about this available on the web, but basically YAGNI points out a number of risks in generalizing without the benefit of several actual use cases at hand, including the possibility that multiple use cases might not actually appear. Or, more subtly, the lack of actual use cases requires one to make assumptions about what's necessary in the future. These assumptions can be, and often are, incorrect.

Title: When to prefer a generalized solution over solving specific cases

Body:
In programming we're often faced with a choice: cover each conceivable use case individually, or solve the general problem:

Its obvious that solving the immediate problem is faster, however creating a generalized solution will save time in the future.

How do I know when it's best to try and cover a finite list of cases, or make a generic system to cover all possibilities?


答: Do it once, do it twice, do it three times, generalize.</p>


问:
Can testers peer review the developers' design and code?
I am a junior developer for a small business using scrum / agile development.  A long-term goal of ours is to be appraised at CMMI lvl 2.  We have a team of 3 senior developers who implement user stories and a handful of junior developers for support.

We are moving towards a "three amigos" methodology, especially in regard to separating the duties of development and testing (the third amigo being the product owner / business stakeholders).  This way our senior developers can focus on implementation and our junior developers can focus as impartial testers.

We are using peer reviews as a specific practice for verifying work products, such as source code.  This paper, http://repository.cmu.edu/cgi/viewcontent.cgi?article=1208&context=sei, describes on p. 19 that an optimal peer review process for design and code ranges from 50-65% of the time spent designing and coding.

My question is this:  is it appropriate for our testers to peer review the developers' design and code?  An advantage would be that the developers can spend more time implementing user stories.  A disadvantage would be that the testers may sacrifice their objective/impartial view of the system, since peer reviewing creates a shared ownership of the code.

答:
You raise several issues in your question, and each deserves some thought, particularly if the CMMi inspectors might be coming to your cubicle or office to ask you about them.  Been there, done that, it can be good if you are prepared, but...  Well, you want to be prepared.  Issues from your description include:

Eligibility: Are junior developers assigned to support as testers eligible to be
reviewers?

Certifiability: Agile + CMMi + code reviews - How to stay agile and meet
CMMi guidelines?

Objectivity: Can code reviewers continue to be objective testers
if they have seen the code?

Eligibility

Do you know the user story?  Has it been flowed into a use case
diagram and to individual use cases with alternate flows?  If not,
the senior developers might not have completed their documentation
enough to provide adequate reference material for the inspection to
begin.

If the reviewed work product is code, do you know the language, and
the coding standard?

If you know these, you have some great tools to give feedback.

As testers,

If you are not involved in reviews of the user stories and use cases, how do you make your test plans for black box and other functional testing?

Similarly, if are involved in glass box testing for statement and/or decision coverage, if you don't read the code, how do you write your test cases?

Agile to me is not very agile if it does not include some degree of TDD (Test Driven Development) and unit test.  Do you have a role running unit tests or perhaps even writing them?  Potentially, this involves not only reading the code, but modifying it as well.

Ultimately my bottom line for you being on code reviews is that it is a great way for experienced developers to share their judgement and domain knowledge with smart but less experienced members of the team, and for less experienced but potentially more recently trained developers to share what they learned in school or from recent experience at other companies.  A win-win provided both developers respect each other.

Certifiablity

CMMi and scrum/agile may sometimes be at odds with one another, particularly in the part that recommends a high proportion (55-60%) of time be spent in code reviews.  This sounds like a very process heavy approach (i.e. not very Agile), and many teams would look for automation and tools and ways to do it faster.

Scrum based teams I have been on used tool facilitated code reviews in which the author identified the commits and the tool showed us the code.  Our tool chain included svn and Atlassian tools Jira, Fisheye, and Crucible.  Crucible tracked the time spent in review, permitted annotations in the code that were notes or that could include defect classifications.  The author could respond to the notes and make changes that would also show up in the inspection.  To close the inspection, the moderator needed to confirm that review issues were resolved.  Sometimes there was a face to face meeting with the inspectors, but this was not always the case.  The tool did a great job of streamlining the mechanics of the inspection.

Pair programming covers some of the same ground as peer reviews.  Two pairs of eyes can do a lot to catch issues as they occur, and can increase velocity or transfer knowledge between developers.  While there may be some group think where one developer talks the other developer into ideas that are wrong, mostly the interaction develops alternatives that are superior to what one would discover.  Also, if you are on your own, you can pretty easily make an interface or other design choice that will prove unfortunate later.

Objectivity

Testers are not the only ones who need to stay objective about the product for verification and validation.  Generally Agile folks who use Scrum might convey a lot of information verbally because they "Working software over comprehensive documentation".  Will you get your test criteria from customers?  From story cards?

Bottom line is that I think that you probably will get at least some of your test criteria from developers and if it makes you feel better, gather all you can from non-code assets (including the draft users manual that better be in progress in parallel with development), then get stuff from the code.

Example of a CMMi Approvable Peer Review Process

Older methodologies like Fagan Inspections did indeed use large time commitments mentioned earlier.  For the duration of the inspection at least, Fagan teams organized into four roles: moderator, author, reader, and tester.

The moderator supervises the inspection to insure it follows the

methodology and coding or documentation standards, records defects for followed up with the author, and provides metrics to the QA team for quantitative analysis against future defect detection.

The author wrote the code or document that was inspected.  During the inspection, his/her job was to listen very closely.  After
the    inspection, the author fixed defects and followed up with the
moderator.

The reader paraphrased the document or code to the team during the inspection.

The tester was usually someone who would receive the work product as a hand-off.  Often, if a system engineer was the author, a developer would be tester.  For a developer, the inspection-tester role would be software tester.  For a tester who made a test plan,

sometimes their inspector-tester would be a system engineer.

Advantages of this approach are that it establishes significant communication between key participants as work products are handed off across the software development life-cycle.  I think it did a good job preventing the tester (and other inspectors) from being drawn into group-think.

Each inspector prepared individually.

The reader, not the author, presented the work product.

If the author had something in their head that was not in the work product, he had a great chance to confront the problem in front of
three inspectors.

The moderator had the authority to encourage thinking and protect against any battle of egos, and with the coding standards and usually
system documentation, and experience, could be the conscience of the
team.

Not enough time for code reviews / inspections?

To the extent you are involve in defining the code review process, you might take a look at this article.  I do not endorse the product he sells, but like his description of the problem and some alternatives.

http://www.methodsandtools.com/archive/archive.php?id=66

His conclusion seems to be that Fagan inspections are the gold standard, but because they are so time consuming, his company ended up only inspecting about 1% of their code.

I have ab ad-hoc technique that I call "quick-hit code reviews".  This technique requires the commitment of one person, because it is simply the software technical lead reading every code change committed to source control when he comes in first thing in the morning.  This works well if the team is in on a different continent, or if the lead is an early or later riser, while the rest of the team is not.  The review rate is 400-500 lines of code per hour (vs. 100 lines per hour for Fagan), so it is less than thorough and not much is recorded.

When faults are found, the action is to send an email to the author either about a fix they should make, or if they are in a different time zone or away for the day, about a fix the lead makes between the review and a private build and smoke test.  I don't believe this is a CMMi certifiable methodology.  It depends highly on the ability of the lead and their knowledge of the code, and is little help catching with subtle problems (unless they are like your own past mistakes).  I used it when I had a new team on some code that was hard to maintain.  I believe the time spent was paid back in reduced testing and reduced latency between work and rework.


问:
Can I consider interface methods as abstract methods?
I was thinking about that, and I had some doubts.

When I declare an interface, for example:

```<code>public interface MyInterface
{
   public void method1();
   public void method2();
}
</code>```

Could these interface methods be considered abstract? What I mean is that the concept of an abstract method is:

An abstract method is a method that is declared, but contains no implementation.

So, could these methods be considered abstract? They are not "pure" abstract methods as I'm not using the abstract word, but conceptually, it looks like they are.

What can you tell me about it?

Thanks.

答:
Abstract classes can have abstract methods.

Interfaces can only have abstract methods.

method1() and method2() in your example are abstract methods.


问:
Can a loosely typed language be considered true object oriented?
Can a loosely typed programming language like PHP be really considered object oriented?

I mean, the methods don't have returning types and method parameters has no declared type either.

Doesn't class design require methods to have a return type?
Don't methods signatures have specifically-typed parameters?

How can OOP techniques help you code in PHP if you always have to check the types of parameters received because the language doesn't enforce types?

Please, if I'm wrong, explain it to me.

When you design things using UML, then code classes in PHP with no return-typed methods and no-type parameters... Is the code really compliant with the UML design?

You spend time designing your software architecture, then the compiler doesn't force the programmer to follow your design while coding, letting he/she assign any object variable to any other variable with no "type-mismatch" warning.

答:
Doesn't class design need methods to have a return type?

Not really.

Doesn't methods signatures have specifically-typed parameters ?

Sure. Just because the types aren't enforced by the compiler doesn't mean that there's not implied contract and semantics that the methods require/implement.

How can OOP techniques help you code in PHP if you have to always check the types of parameters received because the language doesn't enforce types ?

By focusing on Object Oriented Programming. Again, how you organize the implied contracts of dynamic languages in your design is where OO comes into play.


答:
Doesn't class design need methods to have a return type?

Why?  You aren't modifying the code itself at runtime, so the method has a return type whether it's predeclared or not.  Just because it can't be enforced doesn't mean it doesn't exist — it can clearly be inferred from the code itself.

Doesn't methods signatures have specifically-typed parameters ?

Again, there's nothing to say that the method can't simply be liberal in what it receives.  Get user by id? Sure, pass in a String or an integer.  How does that break object-oriented-programming?

How can OOP techniques help you code in PHP if you have to always check the types of parameters received because the language doesn't enforce types ?

Here, based on the above arguments, I again fail to see why "extra checking", even if needed, renders OOP techniques powerless.

The loosely-typed languages that I am familiar with don't have method overloading, which is often used to make methods more flexible on input (while still using the same name), so I fail to see much difference from using one method and "extra checking".  A diligent developer can write the same method, with the same contract, stability and security in a loosely-typed language.

When you design things using UML, then code classes in PHP with no return-typed methods and no-type parameters... Is the code really compliant with the UML design ?

Well this depends on your method itself, doesn't it?  What it actually does with the inputs and what it outputs?

Typing still exists

The bottom line is, types still exist, they are just loose or weak1, and these systems can even have certain advantages.

In fact, some IDEs like those by JetBrains (IntelliJ, PHPStorm) support all kinds of type hinting using PHPDocs for PHP.  As I've used it, it provides almost all the convenient warnings, click-through, code-completion, etc. that an IDE for a strongly-typed can provide.

1: Both "loose" and "weak" are just a poor grouping anyway; there are so many different type systems that these terms are likely to cause confusion.  See Eric Lippert's informative perspective on this topic on Stack Overflow.

Method doc and inline example

```<code>/**
 * @static
 * @param mixed $id
 * @return User
 */
public function getUserById($id) {
    ....
}

public function printUserName() {
    // code completion provided on getName method because of @return
    $name = $this->getUserById("5")->getName();

    // type hinting for arrays
    /** @var User[] $users */
    $users = array(new User());
}
</code>```

Casting example

```<code>public function checkUser(User $user) {
    if ($user instanceof Administrator) {
        /** @var Administrator $admin  */
        $admin = $user;
        $admin->logAccess();
    }
}
</code>```

Title: Can a loosely typed language be considered true object oriented?

Body:
Can a loosely typed programming language like PHP be really considered object oriented?

I mean, the methods don't have returning types and method parameters has no declared type either.

Doesn't class design require methods to have a return type?
Don't methods signatures have specifically-typed parameters?

How can OOP techniques help you code in PHP if you always have to check the types of parameters received because the language doesn't enforce types?

Please, if I'm wrong, explain it to me.

When you design things using UML, then code classes in PHP with no return-typed methods and no-type parameters... Is the code really compliant with the UML design?

You spend time designing your software architecture, then the compiler doesn't force the programmer to follow your design while coding, letting he/she assign any object variable to any other variable with no "type-mismatch" warning.

Body:
Doesn't class design need methods to have a return type?

Why?  You aren't modifying the code itself at runtime, so the method has a return type whether it's predeclared or not.  Just because it can't be enforced doesn't mean it doesn't exist — it can clearly be inferred from the code itself.

Doesn't methods signatures have specifically-typed parameters ?

Again, there's nothing to say that the method can't simply be liberal in what it receives.  Get user by id? Sure, pass in a String or an integer.  How does that break object-oriented-programming?

How can OOP techniques help you code in PHP if you have to always check the types of parameters received because the language doesn't enforce types ?

Here, based on the above arguments, I again fail to see why "extra checking", even if needed, renders OOP techniques powerless.

The loosely-typed languages that I am familiar with don't have method overloading, which is often used to make methods more flexible on input (while still using the same name), so I fail to see much difference from using one method and "extra checking".  A diligent developer can write the same method, with the same contract, stability and security in a loosely-typed language.

When you design things using UML, then code classes in PHP with no return-typed methods and no-type parameters... Is the code really compliant with the UML design ?

Well this depends on your method itself, doesn't it?  What it actually does with the inputs and what it outputs?

Typing still exists

The bottom line is, types still exist, they are just loose or weak1, and these systems can even have certain advantages.

In fact, some IDEs like those by JetBrains (IntelliJ, PHPStorm) support all kinds of type hinting using PHPDocs for PHP.  As I've used it, it provides almost all the convenient warnings, click-through, code-completion, etc. that an IDE for a strongly-typed can provide.

1: Both "loose" and "weak" are just a poor grouping anyway; there are so many different type systems that these terms are likely to cause confusion.  See Eric Lippert's informative perspective on this topic on Stack Overflow.

Method doc and inline example

/**
 * @static
 * @param mixed $id
 * @return User
 */
public function getUserById($id) {
    ....
}

public function printUserName() {
    // code completion provided on getName method because of @return
    $name = $this->getUserById("5")->getName();

    // type hinting for arrays
    /** @var User[] $users */
    $users = array(new User());
}

Casting example

public function checkUser(User $user) {
    if ($user instanceof Administrator) {
        /** @var Administrator $admin  */
        $admin = $user;
        $admin->logAccess();
    }
}


问:
Should I take care of race conditions which almost certainly has no chance of occuring?
Let's consider something like a GUI application where main thread is updating the UI almost instantaneously, and some other thread is polling data over the network or something that is guaranteed to take 5-10 seconds to finish the job.

I've received many different answers for this, but some people say that if it is a race condition of a statistical impossibility, don't worry about it at all but others have said that if there's even a 10-53% (I kid you not on the numbers, this is what I've heard) of some voodoo magic happening due to race condition, always obtain/release locks on the thread that needs it.

What are your thoughts? Is it a good programming practice to handle race condition in such statistically-impossible situations? or would it be totally unnecessary or even counterproductive to add more lines of code to hinder readability?

答:
Therac-25!

Developers on the Therac-25 project were pretty confident about the timing between a UI and an interface related issue in an therapeutic XRAY machine.

They should not have been.

You can learn more about this famous life-and-death software disaster at:

http://www.youtube.com/watch?v=izGSOsAGIVQ

or

http://en.wikipedia.org/wiki/Therac-25

Your application may be much less sensitive to failure than medical devices.  A helpful method is to rate risk exposure as the product of the likelihood of occurrence and the cost of occurrence over the life of the product for all the units that could be produced.

If you have chosen to build your code to last (and it sounds like you have), you should consider Moore's law that can easily lop off several zeros every few years as computers inside or outside your system get faster.  If you ship thousands of copies, lop off more zeros.  If users do this operation daily (or monthly) for years, take away a few more.  If it is used where Google fiber is available, what then?  If the UI garbage collects mid GUI operation, does that affect the race?  Are you using an Open Source or Windows library behind your GUI?  Can updates there affect timing?

Semaphores, locks, mutexes, barrier synchronization are among the ways to synchronize activities between threads.  Potentially if you are not using them, another person who maintains your program might and then pretty quickly assumptions about relationships between threads can shift and the calculation about the race condition might be invalidated.

I recommend that you explicitly synchronize because while you might not ever see it create a problem, a customer might.  In addition, even if your race condition never occurs, what if you or your organization are called to court to defend your code (as Toyota was related to the Prius a few years ago).  The more thorough your methodology, the better you will fare.  It might be nicer to say "we guard against this unlikely case like this..." than to say, "we know our code will fail, but we wrote down this equation to show it won't happen in our lifetime.  Probably."

It sounds like the probability calculation comes from someone else.  Do they know your code and do you know them enough to trust that no error was made?  If I calculated a 99.99997% reliability for something, I might also think back to my college statistics classes and remember that I did not always get 100%, and back off quite a few percent on my own personal reliability estimates.


答:
The classic attributes of OOP are: inheritance, polymorphism and encapsulation. No mention of strong typing.

I do not know PHP, but I have coded OOP Python and it feels just like OOP C#.


问:
Would this data requirement suit a Document -Oriented database?
I have a requirement to allow users to fill in journal/diary entries per day.
I want to provide a handful of known journal templates with x columns to fill in. An example might be a thought diary; a user has to record a thought in one column, describe the situation, rate how they felt etc.

The other requirement is that a user should be able to create their own diary templates. They might have a need for a 10 column diary entry per day and might need to rate some aspect out of 50 instead of 10.

In an RDBMS, I can see this getting quite complicated. I could have individual tables for my known templates as the fields will be fixed. But for custom diary templates I imagine I would would need a table storing custom_field_types (the diary columns), a table storing entries referencing their field types (custom_entries) and then a third custom_diary table which would store rows matching custom_entries to diaries.

Leaving performance / scaling aside, would it be any simpler or make more sense to use a document oriented database like MongoDB to store this data?

This is for a web application which might later need an API for mobile devices.

答:
I think the fact that you're asking about a document database is likely reason enough to use it.  Generally the most important aspect to think about in choices like this is whether the team has skill/experience with a technology.  If you're open to trying a document database, that might be enough.

But, from a more technological aspect, document databases generally mean things like no database-level joins, no transactions, no ACID guarantees.  I say "generally" because each document database is different.  Those sorts of things need to be implemented at the application level.  If you don't generally have concurrent updates to data (or no updates, i.e. once a document is written, it's only read) then document databases are optimal because you may not need transactions.

If you're looking at structured but unspecific data then RDBMS, as you say, might be a lot of work.  If each user has the potential to store what effectively ends up being custom-structured data, a document database seems like a better choice.  But, it depends.  A key/value store might also work very well in a situation like this.

If you're looking at things like ETL or reporting, then RDBMS' can sometimes be a better choice.  They have a better selection of tooling to support things like this.  Any replication needs might also influence whether you choose RDBMS or not.  Some document databases support replication and many support sharding.

if you're looking at distribution of data, nosql in general is often a better choice.  RDBMS can be made to work in situations like this but can end up with some performance issues.  This usually isn't an issue until you reach very high loads over very big data.

Given the current state of document databases, I can't really think of many situations where they don't really fit from simply a data-storage point of view.  There are very high-load big data situations where certain implementations might introduce some performance issues.  But that's really rare--and often ends with the creation of a new nosql database designed specifically for that organization's scenario.

I would suggest implementing a quick and dirty proof of concept to get a feel for the work involved.  If you think its drastically less work than an RDBMS then that might be the deciding factor--unless SQL-specific tooling like 3rd-party reporting (like BI) is a requirement.


问:
Whats a better way of designing this class
Currently I have some code like this:

```<code>OntologyGenerator generator = new OntologyGenerator();
generator.AddOntologyHeader("Testing");
generator.AddClassDeclaration(owlBuilder);
generator.AddSubClass(owlBuilder);
generator.AddAnnotationAssertions(owlBuilder);
</code>```

where that OwlBuilder param you see being passed has collections of objects like this:

```<code>public class OwlLBuilder: IOwlLBuilder
{
       private ICollection<IOwlClass> owlClasses = new Collection<IOwlClass>();
       private ICollection<IOwlRelation>  owlRelations = new Collection<IOwlRelation> ();
}
</code>```

so for example when I say generator.AddClassDeclaration(owlBuilder); it will be looping through owlClasses collection of that owlBuilder param and do some stuff to it...

I feel it is an ugly design. Do you have any other better design suggestions, well with some code sample so I can have the big picture of what I should do in my head!

答:
I have 2 opposing ideas:

Get rid of the IOwlBuilder completly and pass collection themselves.

```<code>OntologyGenerator generator = new OntologyGenerator();
generator.AddOntologyHeader("Testing");
generator.AddClassDeclaration(classes);
generator.AddSubClass(relations); // ??
generator.AddAnnotationAssertions(??);
</code>```

Create an interface that will provide all data needed for creation.

```<code>public interface IOntologySource
{
     public string GetHeader {get; }
     public ICollection<IOwlClass> Classes {get; }
     public ICollection<IOwlRelation> Relations {get; }
}
</code>```

And then use it as parameter in constructor.

```<code>OntologyGenerator generator = new OntologyGenerator(ontologySource);
</code>```

But it seems like you are not telling us everything and there is much more going on with your code. You should add more details if you want better answer.

Body:
I have 2 opposing ideas:

Get rid of the IOwlBuilder completly and pass collection themselves.

OntologyGenerator generator = new OntologyGenerator();
generator.AddOntologyHeader("Testing");
generator.AddClassDeclaration(classes);
generator.AddSubClass(relations); // ??
generator.AddAnnotationAssertions(??);

Create an interface that will provide all data needed for creation.

public interface IOntologySource
{
     public string GetHeader {get; }
     public ICollection<IOwlClass> Classes {get; }
     public ICollection<IOwlRelation> Relations {get; }
}

And then use it as parameter in constructor.

OntologyGenerator generator = new OntologyGenerator(ontologySource);

But it seems like you are not telling us everything and there is much more going on with your code. You should add more details if you want better answer.