Learning Java Basic For Android

Learn the basic of Java programming for Android development.
REPLACE ALL IMAGES WITH MY OWN IMAGES LATER!!!!!

JAVA TUTORIAL

Android N and later uses Java 8 syntax because Google is moving from the proprietary JDK framework to the OpenJDK framework

You should already have a basic knowledge of programming constructs from any programming language. They include, variables and arrays, conditional statements, functions and loops.

In this tutorial we will mainly highlight concepts that are UNIQUE to Java and OOP. If you need knowledge of basic programming constructs, see my app “The ABCs of Programming Constructs” shown on the left.

Object-Oriented Programming (OOP) is NOT a programming language but a methodology (a particular set of methods or rules for programming). While OOP programming concepts and constructs are similar to all languages, where they differ is in their syntax (the way they are written).

There are three key terms that you need to know when dealing with Object Oriented Programming.

  • Properties (class variables) are used to STORE data.
  • Methods (class functions) are used to MANIPULATE data. A function does one of two things—return a value or perform an action.
  • Events (specialized functions) are triggers for an object to do something.

Hence, properties and methods allow an object to be CUSTOMIZED. Properties give unique attributes to an object instead of having each instance of an object having the same attributes. Attributes (e.g., color, height, width) describes the CURRENT STATE of an object. Objects obtain interaction with the outside objects through their methods that they expose.

How does Java stack up with other OOP languages?

Below is a summary of some of the most common languages and what they support:

Language Type Create Inheritance Use
Typing
Call to super Use Private Methods Use Abstract Classes Implement Interface
Java Single static super Yes Yes Yes
C# Single static base Yes Yes Yes
VB.NET Single static MyBase Yes Yes Yes
Objective-C Single static/dynamic super No No Protocols
C++ Multiple static class name Yes Yes Abstract Class
Ruby Mix-ins dynamic super Yes N/A N/A
JavaScript Prototype dynamic N/A Yes N/A N/A
  • C++ supports multiple inheritance. Ruby does also using a feature called Mix-ins.
  • JavaScript is an informal OO language in that it does not have classes. However, it uses prototypes to create inheritance.
  • Objective-C implement interface using a feature called Protocols.
  • Most languages are statically type (all variables are declared with a specific data type). However, Objective-C, Ruby and JavaScript supports dynamically types which does not support interfaces.
  • Objective-C is the only language listed that does not provide private methods. However there are ways to simulate it.
  • Objective-C does not support abstract classes. However, there are workarounds.
  • Objective-C supports interfaces using what is called protocols.
  • Because C++ supports multiple inheritance, there is no interface concept. However, you can implement it by inheriting multiple abstract classes that does not have any methods.

Key OOP Concepts

Class—is a SELF-CONTAINED set of instructions (properties and methods) on how to CREATE an object. Hence, a class is a BLUEPRINT on how to build an object. It is not the object but a set of instructions on HOW TO build an object. If you are building a house from a blueprint, you would not set the blueprint on the carpet in your office and stand on it and say this is where my bed room is.

  • All OOP languages come with a set of built-in classes called a standard/class library (e.g., Java Class Library) or a framework (e.g., .NET Framework) that you can start to use right away instead of having to create a class for everything that you do which would be very time-consuming. However, you will typically still new to write your own classes for a particular need in your app.
  • As an advanced topic on classes, you can also nest classes for the following reasons:
    • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
    • It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
    • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.

Object—once an object is created, it contains ALL of the properties and methods of its class and it works independent of other objects create by the same class.

  • Because a single class can create multiple copies of an object, each copy is called an INSTANCE of that class. The process of creating an object is called INSTANTIATION.
  • Because each instance of a class is a new object, they all have to have a unique name so that they can be reference (talked to) in your code.
  • Objects can be visible (e.g., box) or invisible (e.g., date, time, sound). Like the real world, invisible objects are DISPLAYED (made visible) through visible objects. For example, while you cannot see “time,” you can “see” it displayed through other objects like a watch, clock, computer, etc. Again, while you cannot see “date,” you can “see” it displayed through other objects like a calendar, phone, computer, etc.
  • ALL objects have two major characteristics that are sometimes referred to by difference names but the concepts are the same:
    • Properties and Methods
    • States and Behaviors
    • Attributes and Operations
    • Data and Logic
      NOTE:
    • We will use the words properties and methods in this training module.
    • The first word (e.g., properties or attributes) represents the CURRENT STATE of the object and the second word (e.g., behaviors or operations) represents the STATE it can CHANGE to.
    • An object STORES its STATES (variables) in what are called FIELDS and EXPOSES its BEHAVIORS (functions) in what are called METHODS.
  • You can determine is something is an object in OOP if it is a noun. Remember, for elementary school that a noun represents a person, place, thing, idea or concept (e.g., car, house, gamer, event). As an alternative, you can also place the definite article “the” in front of them (e.g., the car, the house, the gamer, the event). Hence, objects in OOP mimics real world objects.

Abstraction— to “abstract” (express a quality or characteristic apart from any specific object or instance) the ESSENTIAL ELEMENTS of an object. For example, we do not want to create a separate class for a small house or a separate class for a large house but simple ONE class that has characteristics COMMON to ANY house.

Encapsulation—to “encapsulate” (to become enclosed in as if in a capsule) an object properties and methods INSIDE of a class definition to protect it from the outside. This is akin to an encapsulated pill that protects the content of the medicine on the inside of the capsule. Encapsulation also “hides” the internal working on an object. For example, you don’t know or you don’t care how the internal mechanics of a car engine works—all you care is that the engine works when you get into it to drive it. Encapsulation encloses the internal workings of an object in a “black box” of sort. The object should not reveal anything about itself other than what is actually needed by other objects. For example, the engine reveals its gears to the transmission which reveals itself to the axles that in turn turns the wheels.

  • Encapsulation is sometimes referred to as DATA HIDING, where you “hide” the data of the object and only “expose” what is needed—its API (Application Programming Interface).
  • Encapsulation is also responsible for REDUCING DEPENDENCES on other objects so that if a change needs to be made in a class, it does not cascade to other classes or more accurately objects based on those classes so that they would need changing to.

Inheritance—instead of creating a similar class from start-to-finish, inheritance allows you to create another class that inherits all of the properties and methods of its parents. However, the child class can have its own set of properties and methods independent of its parent class. Also, that object can override properties and methods of its parent class. In real life, children inherit properties (e.g., skin, hair and eye color) of their parents unless they define their own properties (e.g., change their hair color). The relationship between the parent and child class is called the Superclass (parent) and the Subclass (child), respectively. In it important to note that when changes are made to the parent class, those changes may cascade to any children classes because they are based on the parent class. Inheritance allows you to reuse existing code.

  • Once you have created a class that inherits all of the properties and methods of its parent class, you can gain access to those properties and methods using the keyword super (e.g., super.myParentClassMethod).
  • Inheritance does not restrict you from adding additional properties and methods to the new class.
  • Classes can inherit from other classes as you will see later. This is akin to a child inheriting from its parent which in turn inherited from its parent and so on.

Polymorphisim—“poly” means “many” and “morph” means “form” so polymorphism is creating “many forms” of the same class by OVERRIDING (modifying existing) properties and methods of its parent class OR by ADDING NEW properties and methods that does not exist in its parent class  to create a custom class from it in another form. For example, a House class that was based on its parent class can override a property called elevation to change the look of a custom house.

Knowing all of these concepts will help you to make your code more efficient. For example, creating multiple small objects instead of one large object has the following advantages:

  • Modular—source code of an object can be maintained independently of the source code of other others so that that object can be used anywhere in your app. (OOP concept: Packaging)
  • Data Hiding—object data can be hidden from outside world and can only be given access when needed (OOP concepts: encapsulation, properties and methods).
  • Code re-use—code can be re-used in other parts of your app (OOP concept: Inheritance)
  • Mobility—objects can stand by themselves and moved about at will or even deleted if a feature is no longer needed (OOP concept: Objects)
  • Easy Debugging—because objects work independent of each other and are responsible for their own problems, your app will be easier to debug because you can remove it from your app and replace it with another object that works (OOP concepts: Instantiation)

There are several steps that you can used to determine how to build an app:

Determine the functional (e.g., features) and non-functional (e.g., help) requirements that the app MUST have not like to have. A common practice is to use the acronym FURPS+ when referring to these requirements:

  • Functionality - Capability and features
  • Usability - Human Factors/Aesthetics/Documentation/Responsiveness
  • Reliability - Robustness/Durability/Resilience
  • Performance - Speed/Scalability
  • Supportability - Service/Maintenance
    • + Design requirements – (e.g., iPhone, Android or both)
    • + Implementation requirements – (e.g., programming language used, data-base driven)
    • + Interface requirements – (e.g., how does it interfaces with other systems)
    • + Physical requirements – (e.g., physical constants like size, weight)
  • Describe what the app will do
  • Identify the key objects the app will used to create the classes
  • Determine how objects interactive with each other
  • Create a class diagram depicting the app

Unified Markup Language

Once you have established a list of "must-have" requirements, you can now set your attention on how a user will use the app by writing a use case diagram that has a:

  • Title (What is the goal of the app?)—a  short phrase using a verb (e.g., register a new user)
  • Actor (Who is using the app?)—the term actor is used because it could be someone other than a user (e.g., customer, student, or even an external source such as a database or another app). You may have more than one actor (e.g., employee, HR, manager or admin with different security roles)
  • Scenario (How will the app be used?)—information on how to accomplish goal in a series of sentences or as a number of bullet list that can easily be read by a user.

    EXAMPLE: User provide login credentials (username and password). App validates user credentials and open home page or activity. User browser content of app. User log out of app.

    NOTE: You can also include additional steps (e.g., if the user did not entered the correct credential what would happen—he/she may get locked out of the app)

User Story is simpler than a use case and it has the following syntax that are typically written on index cards:

  • As a… (user type)
  • I want… (goal)
  • So that… (reason)

EXAMPLE:

  • As a user
  • I want to be able to search for key words
  • So that I can have a better understand of the concept

    NOTE:
     You will likely have multiple user stories (e.g., admin, customer, HR).

    NOTE: For both use cases user stories, it is important to note that you are describing INTENTIONS not how it is done (not click this, do that).

Now that you have determine the requirements for an app and the users of the app, it is time to identify classes that we can create and show how they relate to one another.

  1. Since classes are nouns, review your scenario and look for nouns in the paragraphs or list to determine what potential classes you may need to create and write them in a list.
  2. Remove any duplicate items or items that are not needed.
  3. Place each item in a box so that you can see the potential relationships between them.
  4. Draw lines between the box to show relationships between the various items
  5. Add key words between boxes and add symbols (1 and *) only if necessary to show multiple relationships (e.g., shopping cart can contain multiple items).

REPLACE LATER WITH OWN SCREENSHOT:



NOTE: This is similar to database development where you:

  • Create IT
  • Relate IT
  • Populate IT

Like nouns that were used to identify the potential classes needed, now we will look for verbs or verb phrases in our scenario to ASSIGN potential responsibilities to methods for that class.

  1. Review your scenario and look for verbs or verb phrases in the paragraphs or list to determine what potential methods you may need to create and write them in a list.
  2. Remove any duplicate items or items that are not needed.

NOTE: It is sometimes difficult to determine where to assign a responsibility (method) to what class. For example, if you have a responsibility called "Check Order", do you place that responsibility on the Order or Customer class? It is important to remember that an object is responsible for itself. So even though the customer may want to know the status of an order, it is the responsibility of the Order class to do that function (method)—getOrder().

REPLACE LATER WITH OWN SCREENSHOT:



NOTE: It is important to note that the screenshot is not showing who initiate these functions (e.g., customer) but where the responsibilities lies for performing them (e.g., order). While the customer may be initiating actions like get order or confirm order, these actions are ACTUALLY performed in the Order class.

As an alternative to identifying classes, you could use a simpler approach called CRC (Class, Responsibility and Collaboration) Cards that are written on index cards with the Class name on top and then the Responsibilities taking about 2/3 of the card and collaborators taking 1/3 of the card:
REPLACE LATER WITH OWN SCREENSHOT

EXAMPLES:

Now, you are ready to create classes using a class diagram which includes:

  1. Class name
  2. Properties (attributes)
  3. Methods (behaviors/operations)

Steps in writing a class diagrams:

  1. Write Class name with first letter capitalized and is singular.
  2. Write properties using a common naming conventions like camelCase.
  3. Optionally, add data types to the properties (e.g., isLogin: Boolean) and DEFAULT values (e.g., name = "New Employee") using an equal sign and then the data type.
  4. Write methods typically using the prefixes "get" and "set" in front of the methods to describe methods that retrieves or modifies data, respectively. Methods are suffixed with a set of parenthesis (e.g., getName() ) and may have arguments.
  5. Optionally, add return types (e.g., getName(): String) using a colon and then the return type if the method returns a value. If the method performs an action, then you don't use a return type.
  6. Add plus (+) or minus (-) signs BEFORE the properties and methods to denote if they are private or public, respectively. When the sign is minus (private), it controls the VISIBILITY of the property or method to other objects. Note that while you can have a property that is private (-name), you can also have a method that is public (+getName) to ascertain its value without changing the value. Methods are typically public. However, there may be cases where you want to make them private. For example, when you want to format a currency value, you can make it private (e.g., formatCurrency) because other objects don't need to access this method directly.
  7. Optionally, you can add notes outside of the class diagram.

    TIP: Many IDEs will automatically generates getters and setters. Many IDEs will automatically generates getters and setters.Many IDEs will automatically generates getters and setters.Many IDEs will automatically generates getters and setters.

REPLACE LATER WITH OWN SCREENSHOT

EXAMPLE OF A CLASS DIAGRAM:

Once you have a class diagram, you can use it to create Java code from it.

REPLACE LATER WITH OWN SCREENSHOT

EXAMPLE:

From this:

To this:

USE MY CODE:

class MyBox {

int height=100;
int width=100;
string color = "blue";

void setHeight (int newHeight) {
height = newHeight;
}

void setWidth (int newWidth) {
height = newWidth;
}

void setColor (int newColor) {
color = newColor;
}

void printProperties () {
System.out.println("Box height: " + height + "Box width: " + width + "Box color: " + color);
}

}

NOTES:

  • Notice that the MyBox class does not contain a main method because it is a blueprint of the object and not the actual object. The responsibility of creating a MyBox object belongs to the class in your app.
  • Method declaration can include several elements:
    • Modifiers—private or public access modifiers (or other that will be discussed later)
    • Return Type—data type of value returned by the method. If the method does an action and not return a value, the keyword void is used instead.
    • Parameters—a comma delimited list of parameters preceded by their data types. If no parameters are needed, the parenthesis can be left blank.
    • Exception list—discussed later.
    • Method body—the code inside of the curly braces.
  • A method signature is defined as the method's name AND its parameter types.
  • It is a common convention to have a method as two words in camelCase where the first word is a verb and the second word is an adjective or noun (e.g., getTotal, setHeight)

class MyBoxDemo {
public static void main(String[] args) {
// Create two boxes
MyBox box1 = new MyBox();
MyBox box2 = new MyBox();

// Invoke box's methods:
box1.newHeight(50);
box1.newWidth(50);
box1.newColor("red");
box1.printProperties();

box2.newHeight(50);
box2.newWidth(50);
box2.newColor("green");
box2.printProperties();
}
}

The output should read:

Box height: 50  Box width: 50 Box color: red
Box height: 25  Box width: 25 Box color: green


NOTES:

  • In the statement (MyBox box1 = new MyBox();), the first MyBox represents the class name and the second MyBox represent a new instance of the MyBox class. While the code make seem convoluted because it has the MyBox name on BOTH side of the equal sign, the syntax is ALWAYS the same and after a while it will become second nature to you to use it.
  • It is a common naming convention to have the first letter of a class capitalized (e.g., MyClass)
  • It is also a common naming convention to have the first word of a method name as  a verb (e.g., getTotal)

QUESTION: What would happen if you don't pass arguments to the methods when the object is instantiated (e.g., box1.newHeight())?

  • The compiler would throw an error because it is EXPECTING arguments.
  • It will work but only give you the defaults values (e.g., Box height:100 Box width:100 Box color:blue)

While the above code works, it will generate an object AND then you have to assign STATES to it. We will see later how to use a constructor method to define the STATES when the object is created.

NOTES:

  • The class definition name is public and start with a capital letter and all of the other code is "encapsulated" inside a set of curly braces (public class Classname {…}).
  • Properties (attributes) are represented as instance variables. Remember, a property is variable of a class. Instance variables are variables that belong to an instance of a class. Any object created from an instance of this class will have a COPY of these variables unique to that object. They are sometimes called fields or members????
  • Methods (behaviors) are represented by functions. Remember, a method is a function of a class. If it performs an action instead of returning a value, it uses the keyword "void."  If it does return a value, it will use the key word "return."
  • Public and private keywords represent the visibility of a property or method.
  • The Java class syntax is identical in C# and similar in other OOP languages like VB.NET, Ruby, etc.

OO Patterns/Principles

Designed Patterns are well-tested best-practices solutions to common software development. For example, there is:

  • MVC—use to create a Model, View and Controller
  • Singleton—used to
  • Observer Design Pattern—used if one object changes it will let other objects know the change took place.
  • Memento Design Pattern—used if an object will changed other objects and be able to undo the last change.

Design Patterns are best known from the book Design Patterns (often referred to as the Gang of Four) that details 23 Design Patterns split in three categories:

Creational Patterns—deals with the creation of objects

Structural Patterns—deals with how classes are designed

Behavioral Patterns—deals with communication between objects

RETYPE IN TEXT

Below is a list of general principles

  • DRY (Don't Repeat Yourself)—don't copy and paste UNCHANGED code block from one part of the code to another. For examples, as you write code and then you realize that the code is similar, you should create a function or method and move this code into it so that it can be SHARED throughout your code. This helps because you have only one place in your code to make changes instead of many. This also holds true for the three D's: Documentation, Database, and Diagrams.
  • Start with a least a basic user stories or use cases so that you don't introduce scope creep or code bloating into your code because extra code will also need to be tested, maintained and debugged.

Unnecessary and duplicated code is referred to a Code Smell.

Code smell, also known as bad smell, in computer programming code, refers to any symptom in the source code of a program that possibly indicates a deeper problem.[1] According to Martin Fowler,[2] "a code smell is a surface indication that usually corresponds to a deeper problem in the system". Another way to look at smells is with respect to principles and quality:[3] "smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality". Code smells are usually not bugs—they are not technically incorrect and do not currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future.

Determining what is and is not a code smell is subjective, and varies by language, developer and development methodology. There are tools, such as Checkstyle, PMD and FindBugs for Java, to automatically check for certain kinds of code smells.

Application-level smells:

  • Duplicated code: identical or very similar code exists in more than one location.
  • Contrived complexity: forced usage of overcomplicated design patterns where simpler design would suffice.

Class-level smells:

  • Large class: a class that has grown too large. See God object.
  • Feature envy: a class that uses methods of another class excessively.
  • Inappropriate intimacy: a class that has dependencies on implementation details of another class.
  • Refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class. See Liskov substitution principle.
  • Lazy class / freeloader: a class that does too little.
  • Excessive use of literals: these should be coded as named constants, to improve readability and to avoid programming errors. Additionally, literals can and should be externalized into resource files/scripts where possible, to facilitate localization of software if it is intended to be deployed in different regions.
  • Cyclomatic complexity: too many branches or loops; this may indicate a function needs to be broken up into smaller functions, or that it has potential for simplification.
  • Downcasting: a type cast which breaks the abstraction model; the abstraction may have to be refactored or eliminated.[7]
  • Orphan variable or constant class: a class that typically has a collection of constants which belong elsewhere where those constants should be owned by one of the other member classes.

Method-level smells:

  • Too many parameters: a long list of parameters is hard to read, and makes calling and testing the function complicated. It may indicate that the purpose of the function is ill-conceived and that the code should be refactored so responsibility is assigned in a more clean-cut way.
  • Long method: a method, function, or procedure that has grown too large.
  • Excessively long identifiers: in particular, the use of naming conventions to provide disambiguation that should be implicit in the software architecture.
  • Excessively short identifiers: the name of a variable should reflect its function unless the function is obvious.
  • Excessive return of data: a function or method that returns more than what each of its callers needs.

    —Wikipedia

    Even if the code is correct and valid there may be "things" that does not "smell" right. Here are some examples of what you can do to resolve them:
    • Long method—if a method has a lot lines of code in it, this is a "dead giveaway" that is should be split up into smaller methods.
    • Short or long identifiers-with the exceptions of standard naming convention for indexes and loops that uses the lower case i, j, k, etc. as their names, you should not use one letter to define variables. Likewise, the identifiers should not be too long, if possible.
    • Pointless comment—if the comment is saying basically the same thing as the code and it is obvious what it does, that comment should be deleted. Use descriptive variables, functions and other names to make code self-documenting or self-commenting.
    • God object—In object-oriented programming, a god object is an object that knows too much or does too much. The god object is an example of an anti-pattern. A common programming technique is to separate a large problem into several smaller problems (a divide and conquer strategy) and create solutions for each of them. Once the smaller problems are solved, the big problem as a whole has been solved. Therefore a given object for a small problem need only know about itself. Likewise, there is only one set of problems an object needs to solve: its own problems.—Wikipedia
    • Feature envy—if one class seems to use all of methods of another class, you should rethink the roles of those classes.

The SOLID Principle by Robert Martin is not a set of rules but guidelines and should be treated as a checklist to create a class design.

Single Responsibility Principle

Open/Close Principle

Liskov Substitution Principle

Integration Segregation Principle

Dependency Inversion Principle

 

  • Single Responsibility Principle—an object should have one primary responsibility. It can have multiple methods that focus on the primary responsibility. In essence, an object should be responsible for itself. The goal here is not to create God objects (See above)
  • Open/Close Principle—an object is open for EXTENSION but close for MODIFICATION. Once code is WRITTEN (Classes, functions, modules) and requirement changes, if you need to add additional functionality, you should write NEW code and NOT change EXISTING code that works. For example, if you created some code and then there was a new business requirement, you can add a new class and if that class need some additional functionality, you should add new code instead of changing the original superclass.
  • Liskov Substitution Principle—objects should be replaceable with instances of their subtypes (subclasses or derived classes) without altering the functionality of the app. You should always be always be able to pass them around and treat them like their superclass.
  • Integration Segregation Principle—many specific interfaces is better than one generic interface. An interface (a list of methods) that a class can choose to implement.  But the list should be small as possible. They should be split into smaller interfaces if they get to big.  This is important because classes can choose to implement multiple smaller interfaces then to be FORCES to implement a large interface that it does not need.
  • Dependency Inversion Principle—depend on abstraction and not concretions methods. You should not TIE concrete objects (objects that need to be instantiated) together. Instead use abstract classes in order to minimize their dependencies between objects.

GRASP (General Responsibility Assignment Software Pattern) is a set of OO design principles that focus on RESPONSIBILITIES. Like the SOLID principle it is a NOT a set of rules but GUIDELINES when creating UML diagrams

Who created this object?

Who is responsible for how these objects  talk to each other?

Who will take care of passing messages received from the UI?

There are nine patterns on GRASP:

  • Creator—creator asks the questions, "Who is responsible for creating an object?", "Does one object contains another object?", and "Will one object know enough to make another object?" If so, nominate those objects with CREATOR role.
  • Controller—If you have a UI and some business classes, you don't want to have high coupling between them to actually tie them directly together.  Instead, you can create a CONTROLLER class between them. You can use the MVC pattern to accomplish this task.
  • Pure Fabrication—If there is something that needs to exist in an app that doesn't announce itself as a class or object or have behavior that doesn't fit in an existing class, you can "fabricate" a new class instead of forcing it into an existing class where it does not belong.
  • Information Expert—a class should be responsible for itself. When figuring out where the responsibility goes, we give it to the class that has the most information needed to fulfill it.
  • Indirection—reduce the amount of coupling between objects by placing an indirection object between them to simplify the amount of connections that each object has to make instead of reducing the number of direct connections.
  • Low Coupling / High CohesionLow coupling means to reduce the amount of required CONNECTIONS between objects to reduce dependencies if you make a change to any object. Low coupling does NOT means NO coupling.  Cohesion is the measure of how focused the internal behavior of a class it which means are all its behaviors relates to a single responsibility. If so, it has a HIGH COHESION. In the end, we want Low Coupling but High Cohesion.
  • Polymorphism—See polymorphism discussed earlier.
  • Protected Variation—design so that changes have minimum impact on what already exists using encapsulation or data-hiding, etc.

Resources

Below is a list of resource books that you can use:

  • Software Requirement by Karl Wiegers—initial stages of determining requirements
  • Writing Effective Use Cases by Alistair Cockburn—use case diagrams
  • User Stories Applied for Agile Software Development by Mike Cohn – user story format
  • UML Distilled by Martin Fowler—UML diagram.
  • Refactoring by Martin Fowler—how to improve code design
  • Design Pattern—by the Gang of Four mentioned earlier written with C++.
  • Head First Design Patterns—design pattern using Java.