Mike Chabot

Wednesday 3/10

Frontend, Backend, DevOps

Thank you for the proposals!

Can we code it now?

Probably not.

2/5

2/19

2/26

3/26

5/21

Team Selection

Client Presentations

Project Proposal

Revised Project Proposal

Final Project Documentation

No class

No class

No class

Project Presentations

5/03

No class

Implementation / Testing / Deployment

81 Days

Package structure

Controller is separate! (All calculations, logic, algorithms  etc.)

View is separate! (All user interactions)

Everything is bundled as one package!

We can import the package and use it!

This was the VC (View and Controller) part of the MVC pattern!

Why structure the code like this?

Architecture is more important than features!

Remember this!

What about the code?

"I like my code to be elegant and efficient.

 

The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.

 

Clean code does one thing well."

Dr. Bjarne Stroustrup

Inventor of C++

"I like my code to be elegant and efficient.

 

The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.

 

Clean code does one thing well."

Dr. Bjarne Stroustrup

Inventor of C++

Meaningful Names

Names are everywhere in code!

int d;
// elapsed time in days
int elapsedTimeInDays;

Chapter 2

float doSomething(float param1, float param2) {
  return param1+param2;
}
float add(float number1, float number2) {
  return number1+number2;
}

Small Functions

1st Rule: Functions should be small

public static String testableHtml(
	PageData pageData,
	boolean includeSuiteSetup
) throws Exception {
	WikiPage wikiPage = pageData.getWikiPage();
	StringBuffer buffer = new StringBuffer();
	if (pageData.hasAttribute("Test")) {
		if (includeSuiteSetup) {
			WikiPage suiteSetup =
              	PageCrawlerImpl.getInheritedPage(
              		SuiteResponder.SUITE_SETUP_NAME, wikiPage
				);
                
        if (suiteSetup != null) {
            WikiPagePath pagePath =
                suiteSetup.getPageCrawler().getFullPath(suiteSetup);
            String pagePathName = PathParser.render(pagePath);
            buffer.append("!include -setup .")
            .append(pagePathName)
            .append("\n");
        }
	}
	WikiPage setup =
	PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);
	if (setup != null) {
      WikiPagePath setupPath =
      wikiPage.getPageCrawler().getFullPath(setup);
      String setupPathName = PathParser.render(setupPath);
      buffer.append("!include -setup .")
      .append(setupPathName)
      .append("\n");
      }
	}
	// ...
}

Chapter 3

2nd Rule: They should be smaller than that!

public static String renderPageWithSetupsAndTeardowns(
	PageData pageData, boolean isSuite
) throws Exception {	
	boolean isTestPage = pageData.hasAttribute("Test");
	if (isTestPage) {
		WikiPage testPage = pageData.getWikiPage();
		StringBuffer newPageContent = new StringBuffer();
		includeSetupPages(testPage, newPageContent, isSuite);
		newPageContent.append(pageData.getContent());
    }
	//...
}

Modular Functions

Functions should do one thing!

They should do it well!

They should do it only!

public static String testableHtml(
	PageData pageData,
	boolean includeSuiteSetup
) throws Exception {
	WikiPage wikiPage = pageData.getWikiPage();
	StringBuffer buffer = new StringBuffer();
	if (pageData.hasAttribute("Test")) {
		if (includeSuiteSetup) {
			WikiPage suiteSetup =
              	PageCrawlerImpl.getInheritedPage(
              		SuiteResponder.SUITE_SETUP_NAME, wikiPage
				);
                
        if (suiteSetup != null) {
            WikiPagePath pagePath =
                suiteSetup.getPageCrawler().getFullPath(suiteSetup);
            String pagePathName = PathParser.render(pagePath);
            buffer.append("!include -setup .")
            .append(pagePathName)
            .append("\n");
        }
	}
	WikiPage setup =
	PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);
	if (setup != null) {
      WikiPagePath setupPath =
      wikiPage.getPageCrawler().getFullPath(setup);
      String setupPathName = PathParser.render(setupPath);
      buffer.append("!include -setup .")
      .append(setupPathName)
      .append("\n");
      }
	}
	// ...
}
public static String renderPageWithSetupsAndTeardowns(
	PageData pageData, boolean isSuite
) throws Exception {	
	boolean isTestPage = pageData.hasAttribute("Test");
	if (isTestPage) {
		WikiPage testPage = pageData.getWikiPage();
		StringBuffer newPageContent = new StringBuffer();
		includeSetupPages(testPage, newPageContent, isSuite);
		newPageContent.append(pageData.getContent());
    }
	//...
}

One Level of Abstraction!

Function Arguments

0 or 1 or 2 parameters ok!

Boolean flags not good!

Argument options might be a solution!

function drawCircle(x, y, z, radius, blacknwhite) {
  // ..
};
function drawCircle(point, radius, color) {
  // ..
};
var point = {
  'x': 0,
  'y': 0,
  'z': 0
};

point.x = 1;
point.y = 7;
point.z = 5;
var circle = {
  'point': [1,5,7], // x,y,z
  'radius': 5,
  'color': 'black'
};

function drawCircle(circle) {
  // ...
}

Code Formatting

Define Style Rules in your team!

Use a Linter!

Formats code automatically!

Chapter 5

Comments

Chapter 4

Comments do not replace good code!

Explain yourself in code!

// C++ comment
/*
 * A multi-line
 * comment.
 * 
 * /
# Python comment

'''

A multi-line 
comment.

'''

Use comments as a placeholder!

// TODO: Please fix this!
/**
* Returns the day of the month.
*
* @return the day of the month.
*/
public int getDayOfMonth() {
  return dayOfMonth;
}

Comments

public class wc {
  public static void main(String[] args) {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String line;
    int lineCount = 0;
    int charCount = 0;
    int wordCount = 0;
    try {
      while ((line = in.readLine()) != null) {
          lineCount++;
          charCount += line.length();
          String words[] = line.split("\\W");
          wordCount += words.length;
      } //while
      System.out.println("wordCount = " + wordCount);
      System.out.println("lineCount = " + lineCount);
      System.out.println("charCount = " + charCount);
    } // try
      catch (IOException e) {
        System.err.println("Error:" + e.getMessage());
      } //catch
  } //main
}

Closing Brace Comments

Object Oriented

Constructor

Instances / Instance Variables

Getters / Setters

Static Methods

Singleton Pattern

More Stuff

CS410 Lecture 13

By Daniel Haehn

CS410 Lecture 13

Slides for CS410 Software Engineering at UMass Boston. See https://cs410.net!

  • 42

More from Daniel Haehn