Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Software Engineering Lecture 0 Annatala Wolf I like to include some extra material for depth and completeness. This means that some of the slides may cover materials or topics that you won’t be directly tested on. Such slides will feature titles ending in *. It may still be useful to understand those slides, though. Often the background content will make it much easier to learn the concepts that we will be testing you on. This course will cover four themes: Software engineering The Java language Industry tools Best practices This initial slide set covers basic details of the Java language, and will span the first few class lectures. This is not a “Java course”. It’s a course in component-based software engineering. 2221 is very hard, and requires a lot of work. There’s a substantial curve at the end, but it’s easy to fall behind. You must pass the final to pass the class. However, it’s more likely that you’ll pass the final and fail the class than fail the final when you would have passed. I recommend focusing mainly on the projects. Building large software would be impossible if we did not have a way to separate our work into independent components! Mathematical modeling will allow you to practice your math-reading and illustrate how specifications can be less ambiguous. Design-by-contract will be a constant theme of the course: the difference between thinking as a client (user) of code, and implementer (writer/maintainer) of code. The free availability of Java and IDE’s such as Eclipse and NetBeans will allow you to do much of your work from home. We’ll cover the core syntax of Java, and discuss both polymorphism and generics as powerful tools to generalize code. We will use our own library of components for teaching purposes (including I/O). Exception handling won’t come up in 2221, but JUnit test cases will be used. The Java programming language is: Familiar: Object-oriented: Secure: Portable: Easy-to-use: Interpreted: Fast enough: C-style syntax no messy global scope can be used on the Internet write once, use anywhere platform-independent usually run through the JVM for almost anything All of our tutorials and instructions are designed for use with Eclipse, though other editors are possible (just not supported). JUnit testing is the industry-standard for unittesting of components, and we’ll show you the right way to test your code. Javadoc auto-documentation is a powerful tool we’ll make use of in all of our code specifications. We’ll also cover topics related to what may be considered “best-practice” in industry. Java gives you a lot of tools, but there are standard approaches to using them. Using them the wrong way can produce bad code that is hard (or even impossible!) to debug. We’ll cover naming conventions, style conventions, and a few common design patterns like the observer pattern and modelview-controller. The primary purpose of programming languages is human readability. Most code passes through the hands of many programmers, and even code you write yourself, you may need to read again someday. Virtually all employers adopt some kind of code conventions. The rules we’ll use as examples are common ones, but on occasion these may err on the side of clarity. You should have some programming experience coming in to this class, and a solid background in mathematics. You’ll need to get quickly up to speed on Java syntax, use of variables, and flow of control statements like if and while. We’ll go over these in the next few lectures, just to be safe. You need to be able to work on your own when presented with something unfamiliar. That’s what this field is all about! All relevant information and resources can be accessed from: http://cse.osu.edu/software/ The 2221 page has links to a “Detailed Schedule”, which contains links to all of your assignments, projects, and labs (by due date). The page also links to Carmen, where your grades are stored (check weekly for errors). Piazza will be used for question/answer feedback between students and faculty. I consider it my job to serve you. If you are having trouble understanding the course material, come see me or a grader. I’ll make as much time as you need for tutoring. But it may not be enough if you fall behind, so I strongly urge you to stay on top of the material. 2221 moves very quickly. Make use of Carmen, Piazza, your classmates, and of course, Google! Information for your particular 2221 section is available by following the correct link at the bottom of the 2221 page. For my sections: http://cse.osu.edu/~wolfann/cse2221/ Here you’ll find links to my schedule, grader information for my sections, details on the final exam time and place (once determined), and links to these slides (I prefer to make my own slide sets, and most students find them useful to study from). Don’t cheat. It’s hard to do in CSE, and will end up hurting you more than helping. Attending COAM meetings is definitely my least-favorite part of this job. I’m required to bring any evidence of academic misconduct to COAM, even if I do not believe any misconduct has occurred. If you took 2221 before, you may not turn in the same work you turned in previously. Your work must be your own. You can (and should) help one another with general use of the system, debugging, and testing; but do not write code or pseudocode for other students. Discussing how to attack a problem is okay; partial solutions are not. If you include code on Piazza, it must be marked as a private discussion. Programming is typically done using an application called an Integrated Development Environment, or IDE. Eclipse is one example. In the IDE, we write code as a text file. The IDE helps format, and highlights some errors. To test our code, we tell the IDE to compile it (turn it into Java bytecode) and run it (using the Java Virtual Machine, or JVM). We’ll get started with this tomorrow. The basic process for making software is pretty simple: write, compile, execute. EXECUTE WRITE INPUT (keyboard, mouse, files, etc.) COMPILE OUTPUT CODE (in text format) (monitor, printer, files, etc.) PROGRAM (executable) COMPILER (decodes your code) COMPUTER (processor) Java differs from this model because it doesn’t generally get turned all the way into machine language. We’ll describe this paradigm in more depth later, but the basic idea is we want Java to work the same way on all systems (PC, Mac, Unix, etc.). So, each system will have its own way to interpret Java. Bugs (errors in a program) are so common that debugging is most of what we do! Compile-time bugs (like syntax errors and type mismatches) prevent a program from even being compiled fully. Run-time bugs occur when something that shouldn’t happen, does (e.g. file not found). Logical bugs are when we don’t don’t get the behavior we want. In Java, each variable or subroutine must appear somewhere in a class. A class is often like a blueprint for a new kind of data. Each class, and also subroutines (procedures and functions) inside it, are contained in a block: a section of code between { and }. Blocks are composed of statements: a bunch of symbols in Java grammar, usually ending with: ; To review some basics, statements come in many flavors: Variable declaration: type name; double percent; String title; Variable assignment: name = expression; percent = 20.0; title = “Magic Duel”; Both combined: type name = expr; double percent = 20.0; String hi = “Hello!”; Procedure call: obj.method(args); rDash.rainBoom(Temp.COOLER, percent); Some statements control whether or not something happens in the program, by prefacing one or more blocks. In this case, each block will contain its own statements, and the blocks are also considered part of the larger control statement. if (condition) { i = 0; } else { i++; } Each boxed element here is considered one statement. Note that the if-else statement includes both of its blocks (as well as the statements inside). package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny main class used to test output. */ public class HelloWorld { /** * main() is the entry point for our program. */ public static void main(String args[]) { System.out.println(“Hello, world!”); } } package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny main class used to test output. */ public class HelloWorld The { package statement appears outside the class body. It tells Java what entry pointa for our program. package file belongs to. /** * main() is the */ public static void main(String args[]) { Packages are used to System.out.println(“Hello, world!”); group similar classes. } } Java files are organized into packages. Each package forms a namespace to distinguish between classes with the same name. For simplicity we won’t be using packages, but you should when you program in Java. If you start a package name with a reverse URL you own, it guarantees uniqueness: package edu.osu.cse.wolfann.ponyband; package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny main class used to test output. */ public class HelloWorld { /** * main() is the entry point for our program. */ public static void main(String args[]) { System.out.println(“Hello, world!”); Comments beginning with /** are called Javadoc comments. } We’ll discuss commenting practice in detail in a later lecture. } package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny main class used to test output. */ public class HelloWorld { /** * main() is the entry point for our program. This is the public class for */ this file. The file’s public static void main(String args[]) { name must beworld!”); HelloWorld.java System.out.println(“Hello, } (same as the class name). } package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny main */ public class HelloWorld { This is the class body (or definition) for our class used to test output. HelloWorld class. /** * main() is the entry point for our program. */ public static void main(String args[]) { System.out.println(“Hello, world!”); } } package edu.osu.cse.wolfann.cse2221.examples; Our HelloWorld class contains a special method called the main method. This means /** it can be selected as the main class (the class * HelloWorld is a tiny main class used to test output. that starts a Java program). */ public class HelloWorld { /** * main() is the entry point for our program. */ public static void main(String args[]) { System.out.println(“Hello, world!”); } } package edu.osu.cse.wolfann.cse2221.examples; /** * HelloWorld is a tiny classbody used for to main(), test output. Here is themain method */ which is both the entry point (beginning) public class and HelloWorld { (end) for any program that exit point selects HelloWorld as its main class. /** * main() is the entry point for our program. */ public static void main(String args[]) { System.out.println(“Hello, world!”); } } Every public top-level class has its own file. The filename must match the class name. You can put additional non-public and/or nested classes in the same file, but this is advanced. Whenever you run Java code, one of the files must be designated as the main class file. This file must contain a main() method. A Java program may consist of many Java files. At least one of these files must contain a special method, called the main method. When you run a Java program, you have to choose which class will be the program’s main class. That class’s main() method is where the program will begin. The header for main() must be exactly: public static void main(String args[]) The reason Java works everywhere is that it isn’t usually compiled all the way to machine language. Instead, Java compiles to another language called Java bytecode (mentioned previously). When Java runs on your computer, it effectively emulates a fictitious computer: one that understands Java bytecode. This simulator is called the Java Virtual Machine (JVM). import components.simplewriter.SimpleWriter; import components.simplewriter.SimpleWriter1L; public final class HelloWorld { private HelloWorld() { } public static void main(String args[]) { SimpleWriter out = new SimpleWriter1L(); out.println(“Hello, world!”); out.close(); } (For brevity, Javadoc comments } have been omitted.) import components.simplewriter.SimpleWriter; import components.simplewriter.SimpleWriter1L; public final class HelloWorld { private HelloWorld() { } This first import statement tells the compiler that every use of public static void main(String SimpleWriterargs[]) is actually{just an SimpleWriter out abbreviation = new SimpleWriter1L(); for components. simplewriter.SimpleWriter. out.println(“Hello, world!”); out.close(); } } You never need to import a class from a different package, but it makes typing the name easier. You can import individual classes, or entire packages of classes. Individual is safer, unless you’re really using all the package’s classes. // Import everything from the package. import components.simplewriter.*; If you do, however, importing a package does not import any of its subpackages. // The second import is not redundant. import java.util.*; import java.util.regex.Pattern; import components.simplewriter.SimpleWriter; import components.simplewriter.SimpleWriter1L; public final class HelloWorld { private HelloWorld() { } The keyword final has many meanings. When public static void main(String args[]) { it’s in front of a class, it SimpleWriter out = new SimpleWriter1L(); means “you can’t extend out.println(“Hello, world!”); this class”. We’ll discuss out.close(); class extensions later. } } The constructor is a special import components.simplewriter.SimpleWriter; method that has the same import components.simplewriter.SimpleWriter1L; name as the class, and no return {type (not even void). public final class HelloWorld private HelloWorld() { } public static void main(String args[]) { Most classes exist to define of object (a new SimpleWriter outa =new newkind SimpleWriter1L(); data type), something we’ll seeworld!”); more later. But this out.println(“Hello, class is only used to hold static code (our main method). out.close(); By making the constructor private, we prevent anyone } from creating a useless HelloWorld object. } import components.simplewriter.SimpleWriter; This is how we handle output with our SimpleWriter import components.simplewriter.SimpleWriter1L; component. This is a safer approach than relying on the system’s default output stream, System.out. public final class HelloWorld { private HelloWorld() { } public static void main(String args[]) { SimpleWriter out = new SimpleWriter1L(); out.println(“Hello, world!”); out.close(); } } SimpleWriter is a class type used to handle output. This output can be to a file (it will create files, but not directories) or it can be to standard out (the monitor, by default). Standard out can also be redirected to a file at the command prompt in Unix (by the user). Using this component will be more flexible than relying on System.out (which has other uses internal to the system). It will also make what we’re doing more explicitly obvious. To create a SimpleWriter output and connect it to standard out, call the parameterless constructor for SimpleWriter1L: SimpleWriter name = new SimpleWriter1L(); To create a SimpleWriter output and connect it to a file, instead call the constructor that takes a String argument: SimpleWriter name = new SimpleWriter1L(“hi.txt”); You probably noticed we’re making a SimpleWriter variable, but then we call the constructor for SimpleWriter1L(). This is clearly a different class! What’s going on here? It’s actually complicated, and we’ll get into it soon. Honest! For now, just use this syntax in your code. SimpleWriter methods you should know: print(String line) will send line to output println(String line) will send line to output, followed by a line break (this is a newline or carriage return, but it depends on system) println() will send just the line break to output close() will close (turn off) the output connection (it’s not guaranteed to write unless you close it!) Example usage: fileOut.println(“Eeyup.”); To create a SimpleReader input and connect it to standard in (the keyboard by default, but it can also be redirected in Unix), just call the parameterless constructor: SimpleReader name = new SimpleReader1L(); To create a SimpleReader input and connect it to a file (error if it’s not found), call the constructor that takes a String argument: SimpleReader name = new SimpleReader1L(“in.csv”); You should know how to use these methods of SimpleReader: String nextLine() will return a String that consists of all the text between the current position in the stream and the next line break or end-of-stream marker (the line break will not be included) boolean atEOS() returns true iff (if and only if) the reader positioned at the end-of-stream marker close() will close the output connection (communication errors may result if you don’t) One reason these components are so “simple” is that they will take care of all the necessary exception-handling for you. Normally, you would want to do this yourself (to handle file errors, for one). However, we’d prefer you focus on the projects without having to worry about try/catch blocks. You should learn exception handling, but we won’t cover it until Software II (this isn’t a “Java course”).