1)never start coding unless you understand the task! 2)gather requirements first. this means...

30
1) Never start coding unless you understand the task! 2) Gather requirements first. This means identify the problem and ask questions about it. Now you kind of know what to do. 3) Analyze requirements to make sure that they are consistent and complete. Now you know that whatever you are going to do is doable. 4) Produce technical specification (i.e. express the requirements in technical terms). Now you know exactly what to do. 5) Think of what steps you need to take solve the problem and express them verbally to obtain a high-level process description. Now you have a process that you can code! 6) Start coding. Problem Solving Problem Solving

Upload: sherilyn-page

Post on 24-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

1) Never start coding unless you understand the task!2) Gather requirements first. This means identify the

problem and ask questions about it. Now you kind of know what to do.

3) Analyze requirements to make sure that they are consistent and complete. Now you know that whatever you are going to do is doable.

4) Produce technical specification (i.e. express the requirements in technical terms). Now you know exactly what to do.

5) Think of what steps you need to take solve the problem and express them verbally to obtain a high-level process description. Now you have a process that you can code!

6) Start coding.

Problem SolvingProblem Solving

Page 2: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

* Split complex task in a series of simple steps.* Identify entities the problem deals with. These

will be your classes.* Identify what data characterizes your entities.

These will be your class properties.* Identify what actions your entities can perform.

These will be your class methods.* Find repeated actions and generalize them.

These will be your utility functions or utility classes. You will reuse them.

* Don’t make any assumptions: check user input and make provisions for worst cases.

Process AnalysisProcess Analysis

Page 3: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Problem: Determine if the email address is valid.

Requirement analysis: What rules can we define to check email address against? What is email address comprised of?

[email protected] Part @ domain subdomain1.subdomain2.tld

Email Validation TaskEmail Validation Task

Page 4: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Core Rules• Single ‘@’ character• Non-empty Local Part• Non-empty domain• Non-empty subdomain(s)• Non-empty TLD• Local Part must not end with ‘.’

Additional Rules7) 1 < TLD length < 78) Local Part length < 659) Domain Length < 25611) Subdomain(s) must not begin with ‘-’ or end with ‘-’12) Check for invalid characters: ‘\\’, ‘”’, ‘<‘, ‘>’, ‘)’, ‘(‘, ‘]’, ’[‘, ’;’, ‘,’,

‘:’, ‘|’13) Domain cannot contain two ‘-’ in a row14) Check TLD against the list of ICANN domains

Email Validation RulesEmail Validation Rules

Page 5: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

General• There has to be LocalPart and Domain separated by ‘@’• Must not contain general illegal characters (‘\\’, ‘”’, ‘<‘, ‘>’, ‘)’, ‘(‘, ‘]’, ’[‘, ’;’, ‘,’, ‘:’, ‘|’)

LocalPart• 0 < Length < 65• Must not end with ‘.’

Domain• 0 < Length < 256• There has to be at least one subdomain and a TLD separated by ‘.’• Must not contain ‘@’• All subdomains must be valid• TLD must be valid

Subdomain• 0 < Length < 64• Must not begin or end with ‘-’

TLD• 0 < Length < 7• Must not contain ‘-’• OR limit TLD choices to domains from ICANN list.

Optimized Rules / Technical SpecOptimized Rules / Technical Spec

Page 6: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Design Choice: Buffer AllocationDesign Choice: Buffer Allocation

Since you do not know sizes of strings you deal with…

a) Do you make an assumption of max string length and allocate fixed-size string buffers on stack?+simpler +faster +robust -limited

b) Or do you allocate memory on heap (e.g. using the new operator)?-harder -slower -err.prone +universal

Page 7: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Choice A: Fixed BuffersChoice A: Fixed Buffers

// Our Assumptions#define MAX_LOCAL_PART 65#define MAX_DOMAIN 256#define MAX_SUBDOMAIN 64#define MAX_TLD 7#define MAX_SUBDOMAINS 10

// Bufferschar LocalPart[MAX_LOCAL_PART];char Domain[MAX_DOMAIN];char TLD[MAX_TLD];char Subdomain[MAX_SUBDOMAINS][MAX_SUBDOMAIN];

Page 8: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Top-Level Class: EmailTop-Level Class: Email

Email – this is the one we validate- Contains Address string (property)- Contains LocalPart (property)- Contains Domain (property)- Can be parsed into LocalPart and

Domain pieces (method)- Can be validated (method)

Page 9: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Email ClassEmail Class

class Email{ public: Email(char* address); public: String Address; EmailLocalPart LocalPart; EmailDomain Domain;

public: bool Parse(); bool IsValid();};

Page 10: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Other ClassesOther Classes

LocalPart- Contains UserName string (property)- Can be validated (method)

Domain- Contains Name string (property)- Contains an array of Subdomains (property)- Contains TLD (property)- Can be parsed (method)- Can be validated (method)

Subdomain- Contains Name string (property)- Can be validated (method)

TLD (closely similar to Subdomain but somewhat different)

- Contains Name string (property)- Can be validated (method)

Page 11: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

EmailLocalPart ClassEmailLocalPart Class

class EmailLocalPart{ public: EmailLocalPart(); public: String UserName;

public: bool IsValid();

private: char UserNameBuffer[MAX_LOCAL_PART];};

Page 12: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

EmailDomain ClassEmailDomain Class

class EmailDomain{ public: EmailDomain() { SubdomainCount = 0; } public: String Name; EmailSubdomain Subdomain[MAX_SUBDOMAINS]; int SubdomainCount; EmailTld Tld;

public: bool Parse(); bool IsValid();

private: char DomainBuffer[MAX_DOMAIN];};

Page 13: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

EmailSubdomain ClassEmailSubdomain Class

class EmailSubdomain{ public: EmailSubdomain(); public: String Name;

public: virtual bool IsValid(); // Virtual means that the method // can be replaced in a derived // class private: char NameBuffer[MAX_DOMAIN];};

Page 14: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

EmailTld ClassEmailTld Class

// Subdomain and Tld are identical, except for// slight differences in validation rules, so to avoid repetition derive

EmailTld class from EmailSubdomain base classclass EmailTld: public EmailSubdomain // EmailTld class is derived from // EmailSubdomain class{ public: EmailTld(); /* public: String Name; */ // Name is inherited from Subdomain // therefore no need to declare again public: virtual bool IsValid(); // Inherited, but we are going to // replace it since TLD validation // is different};

Page 15: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Email Checker Solution: ProcessEmail Checker Solution: Process

1) Separate email into LocalPart and Domain

2) Separate Domain into Subdomain[] array and TLD

3) Apply part validation rules to see if any of them are violated.

Page 16: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Separate Local Part & DomainSeparate Local Part & Domain

1) Determine email Length

2) Determine AtPosition: the position of ‘@’ character in email

3) Copy characters 0…AtPosition to LocalPart

4) Copy characters AtPosition+1…Length to Domain

Page 17: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Pretend that you have already solved concrete tasks (such as copying characters, finding character index, etc.) with the help of String utility class and proceed to construct your abstract solution by referring to String and other concrete classes that you have not yet implemented.

Proceed from Abstract to ConcreteProceed from Abstract to Concrete

Page 18: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

(!) Find repeated tasks that can be generalized and streamlined, e.g.

a) Determining string length (i.e. return the ‘length’ of ‘this string’)

b) Copying a range of characters from one string into another (i.e. copy ‘length’ characters from ‘this string’ starting at ‘startPosition’ into ‘destination’

c) Finding character index (find ‘aChar’ in ‘this string’ starting at ‘startPosition’)

The above (a,b,c) deal with character strings. So let’s pretend that we have a String class that can do all of the above.

ImplementationImplementation

Page 19: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

// String utility classclass String{ public: String() // Default constructor (builds uninitialized String) { Buffer = NULL; } String(char* buffer) // String encapsulates char-array pointer { Buffer = buffer; }

public: int GetLength(); int IndexOf(char aChar, int startPosition); // !! Returns -1 when aChar is not found void CopyTo(int startPosition, int length, String& destination); bool IsValid() // Sanity check { return Buffer != NULL; }

private: char* Buffer;};

String ClassString Class

Page 20: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

String Class Encapsulates char*String Class Encapsulates char*

String class encapsulates char* pointer. Therefore a String must be initialized with a valid char* pointer!

char nameBuffer[100];

String name(nameBuffer);

Page 21: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

We always start with top-level class.

So let’s pretend that Email class is done and the email validation works and we can use it, e.g.

Email email(“[email protected]”);if ( email.IsValid() ) cout << “Email is valid”;else cout << “Email is not valid”;

Where Do We Start?Where Do We Start?

Page 22: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

We start filling in blanks from the constructor of the top-level class.

In the constructor we can refer to other classes we invented even though they are not yet implemented.

Where Do We Go Next?Where Do We Go Next?

Page 23: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Just store the pointer to email address in internal property:

Email::Email(char* address){ // Here we initialize Email’s internal // Address property of type String Address = String(address);}

Constructor Email::Email()Constructor Email::Email()

Page 24: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Now, since we already know what amounts to valid email we can express Email::IsValid() concisely as follows:

bool Email::IsValid(){ // Separate email into LocalPart and Domain return Parse() && // Was parsing OK? LocalPart.IsValid() && // LocalPart OK? Domain.IsValid(); // Domain OK?}

bool Email::IsValid()bool Email::IsValid()

Page 25: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

And we know how to parse EmailAddress into LocalPart and Domain:bool Email::Parse(){ // Find ‘@’ character int atPosition = Address.IndexOf(‘@’, 0); if ( atPosition == -1 ) return false; // Shute, ‘@’ not found! Therefore cannot parse.

// Determine email length int length = Address.GetLength();

// Copy email parts in appropriate buffers Address.CopyTo(0, atPosition, LocalPart.UserName); Address.CopyTo(atPosition + 1, Length - atPosition - 1,

Domain.Name); return true;}

Void Email::Parse()Void Email::Parse()

Page 26: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

And we know what rules we need to check to make sure that LocalPart is valid:

bool EmailLocalPart::IsValid(){ // We do not assume anything, so check UserName string if ( !UserName.IsValid() ) return false;

int length = UserName.GetLength();

// Rule Check: length between 1 and 64 if ( length < 0 || length > 64 ) return false; else return true;}

bool EmailLocalPart::IsValid()bool EmailLocalPart::IsValid()

Page 27: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

And we know what rules we need to check to make sure that Domain is valid:bool EmailDomain::IsValid(){ // Extract subdomains and TLD if ( !Parse() ) return false;

// Check subdomains for ( int i = 0; i < SubdomainsCount; i++ ) if ( !Subdomain[i].IsValid() ) return false;

// Check TLD if ( TLD.IsValid() ) return true; else return false;}

bool EmailDomain::IsValid()bool EmailDomain::IsValid()

Page 28: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

And we know what rules we need to check to make sure that Domain is valid:bool EmailDomain::Parse(){ // We do not assume anything, so check UserName string if ( !Name.IsValid() ) return false;

// Contains at least one ‘.’ if ( Name.IndexOf(‘.’, 0) == -1 ) return false;

// Reset SubdomainCount SubdomainCount = 0;

// Extract subdomains int startPosition = 0; do { int nextPosition = Name.IndexOf(‘.’, StartPosition); if ( nextPosition != -1 ) Name.CopyTo(startPosition + 1, nextPosition - startPosition, Subdomain[SubdomainCount++]); else Name.CopyTo(startPosition + 1, nextPosition - startPosition, Tld) startPosition = nextPosition + 1; } while ( startPosition != 0 );

return true;}

bool EmailDomain::Parse()bool EmailDomain::Parse()

Page 29: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

TLD is a domain, since all domain rule checking applies with an addition of one more TLD-specific rule: TLD cannot contain a ‘-’

// Constructor does nothing special, so we simply call// the base class constructorEmailTld::EmailTld() : EmailSubdomain(){}

bool EmailTld::IsValid(){ return EmailSubdomain::IsValid() && Name.IndexOf(‘-’, 0) == -1;}

bool EmailTld::IsValid()bool EmailTld::IsValid()

Page 30: 1)Never start coding unless you understand the task! 2)Gather requirements first. This means identify the problem and ask questions about it. Now you kind

Just keep filling in the blanks and your program will be done!

In the process you will likely modify your class definitions to accommodate your programming needs as you discover new things.

Class design / programming is an iterative approach. Thus changing and going back and forth is inevitable and normal.

And So On and So ForthAnd So On and So Forth