Haven’t write any thing since last year, thinking might be better to write something than just leave this blog as it is. This article is a brief review of UNSW’s COMP2511 course, which is about object oriented design. Just to prepare for my final exam.
Week 1 (Java Basics)
1. Object: Objects have state (attributes) and behaviour (methods – what the object can do).
2. Class: An object is instantiated from a class and the object is said to be an instance of the class.
- Two object instances from the same class share the same attributes and methods, but have their own object identities and are independent of each other.
3. Constructor: A special method that creates an object instance and assigns values to their attributes.
4. Abstraction: Helps you to focus on the common properties and behaviours of objects.
5. Encapsulation: An OO design concept that emphasises hiding the implementation.
- Encapsulation lead to abstraction.
- Encapsulation of object state implies hiding the object’s attributes.
- Method provides explicit access to the object (getter and setter).
6. Benefits of Encapsulation:
- Encapsulation ensures that an object’s state is in a consistent state
- Encapsulation increases usability
- Encapsulation abstracts the implementation, reduces the dependencies so that a change to a class does not cause a rippling effect on the system
7. Inheritance: models a relationship between classes in which one class represents a more general concept (parent or base class) and another a more specialised class. (is-a type)
- sub-class can extend parent class by defining additional properties
- sub-class can override methods in the parent class
- use “super” in subclass, to invoke a parent’s method.
- Constructors are not inherited. To create an instance of a subclass, there are two ways: 1. Use the default
no-arg
constructor. (This default constructor will make a default call to super() ). 2. Define a constructor in subclass. - The Java language allows a class to extend only one other class – single inheritance.
|
|
Week 2 (Inheritance, Polymorphism, Domain modelling)
1. Object types: All object references have a type.
2. Polymorphism: means “many forms”, an important OO principle to support software reuse and maintenance.
3. Dynamic Binding: ensures that when a method is invoked, you get the behaviour associated with the object to which the variable refers to at runtime. (not determined at compile time)
4. instanceof operator: this method allows us to know what is the actual type of object at run time. if (s instanceof Rectangle) { // do something }
5. Access Modifiers:
6. Association: Association is a special relationship between two classes, that shows two classes are linked to each other. Or combined into some kind of has-a relationship, where one class “contains” another.
- Aggregation: The contained item is an element of a collection but can also exist on its own. (Lab contains Computers)
Composition: The contained item is an integral part of the containing item. Cannot exist without another. (Order has Line Items)
7. Requirements Analysis: determines “external behaviour”. what are the features of the system and who requires these features (actors).
8. Domain Modelling: determines “internal behaviour”. how elements of system-to-be interact to produce the external behaviour.
- Also referred to as conceptual model or domain object model
- Provides a visual representation of the problem.
- Techniques to build a domain model: None/Verb Analysis, CRC Cards.
9. CRC Cards: Class, Responsibility, Collaborator.
Week 3 (Interfaces, Design Principles, LSP)
1. Abstract Class: A class which cannot be instantiated, cannot create object instances of an abstract class.
- Serves as a convenient place-holder for factoring out common behaviour in sub-classes
- An abstract class may define abstract methods.
- A class with one or more abstract methods must be declared as abstract
2. Interface: defines collection of abstract methods. (defining methods without a body)
- Specifies “what” needs to be done, but not “how” to do it
- Classes can implement multiple interfaces, but extend only one
3. Design Smell: is a symptom of poor design, often caused by violation of key design principles.
- Rigidity: Tendency of the software being too difficult to change even in simple ways.
- Fragility: Tendency of the software to break in many places when a small change is made.
- Immobility: Design is hard to reuse.
- Viscosity: changes are easy to implement through “hacks” over “design preserving methods”.
- Opacity: Tendency of a module to be difficult to understand.
- Needless complexity: Contains constructs that are not currently useful.
- Needless repetition: Design contains repeated structures that could potentially be unified under a single abstraction.
4. Coupling: Is defined as the degree of interdependence between components or classes.
- High coupling occurs when one component A depends on the internal workings of B.
- High coupling leads to complex system, with difficulty in maintenance.
5. Cohesion: The degree to which all elements of a component or class or module work together as a functional unit.
- Highly cohesive modules are much easier to maintain and less frequently changed and more reusable.
6. Good software aims for building a system with loose coupling and high cohesion.
7. Design principle: A basic tool or technique that can be applied to designing or writing code to make software more maintainable, flexible and extensible.
- Design principles help eliminate design smells
- don’t apply principles when there no design smells
Design principle 1 (Least Knowledge or Law of Demeter)
Talk only to your friends!
- classes should know about and interact with as few classes as possible
- reduce the interaction between objects to just a few close “friends”
- helps us to design “loosely coupled” system
Rule 1: A method M in an object O call on any other method within O itself
|
|
Rule 2: A method M in an object O can call on any methods of parameters passed to the method M
|
|
Rule 3: A method M can call a method N of another object, if that object is instantiated within the method M
|
|
Rule 4: Any method M in an object O can call on any methods of any type of object that is a direct component of O
|
|
Design principle 2 (Liskov Substitution Principle) (LSP)
LSP is about well-designed inheritance
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
In mathematics, a Square
is a Rectangle
. Indeed it is a specialization of a rectangle. The “is a” makes you want to model this with inheritance. However if in code you made Square
derive from Rectangle
, then a Square
should be usable anywhere you expect a Rectangle
. This makes for some strange behavior.
Imagine you had SetWidth
and SetHeight
methods on your Rectangle
base class; this seems perfectly logical. However if your Rectangle
reference pointed to a Square
, then SetWidth
and SetHeight
doesn’t make sense because setting one would change the other to match it. In this case Square
fails the Liskov Substitution Test with Rectangle
and the abstraction of having Square
inherit from Rectangle
is a bad one.
8. Refactoring: the process of restructuring software to make it easier to understand and cheaper to modify withour changing it’s external, observable behaviour.
- refactoring improves design of software
- refactoring makes software easier to understand
- refactoring helps you find bugs
- refactoring helps you program faster
- refactoring helps you to conform to design principle and avoid design smells
- refactor when you add a function
- refactor when you need to fix a bug
- refactor as you do a code review
9. Common Bad Code Smells:
- Duplicated Code
- Long Method
- Large Class
- Long Paramenter List
- Divergent Change: when one class is commonly changed in different ways for different reasons
- Shotgun Suergery: the opposite of divergent change, when you have to make a lot of little changes to a lot of different classes
10. delegation: The act of one object forwarding an operation to another object to be performed on behalf of the first object
Refactoring Techniques 1: Extract Method
|
|
Refactoring Techniques 2: Rename Variables
Good code should communicate what it is doing clearly, and variable names are a key to clear code. Never be afraid to change the names of things to improve clarity.
Refactoring Techniques 3: Move Method
Generally, a method be on the object whose data uses it.
|
|
Refactoring Techniques 4: Replace Temp with Query
A technique to remove unnecessary local and temporary variables.
Refactoring Techniques 5: Replace conditional logic with polymorphism
|
|
equals() method
Difference between a == b
and a.equals(b)
a == b
checks memory references onlya.equals(b)
calls the eqauls()
method that associated with object a
Bad equals()
:
|
|
Write a good equals() method
|
|