java
CLASS DESIGN GUIDELINES
1. Cohesion • [✓] A class should describe a single entity, and all the class operations should logically fit together to support a coherent purpose. • [✓] A single entity with many responsibilities can be broken into several classes to separate the responsibilities.
2. Consistency • [✓] Follow standard Java programming style and naming conventions. Choose informative names for classes, data fields, and methods. A popular style is to place the data declaration before the constructor and place constructors before methods. • [✓] Make the names consistent. It is not a good practice to choose different names for similar operations. • [✓] In general, you should consistently provide a public no-arg constructor for constructing a default instance. If a class does not support a no-arg constructor, document the reason. If no constructors are defined explicitly, a public default no-arg constructor with an empty body is assumed. • [✓] If you want to prevent users from creating an object for a class, you can declare a private constructor in the class, as is the case for the Math class.
3. Encapsulation • [✓] A class should use the private modifier to hide its data from direct access by clients. This makes the class easy to maintain. • [✓] Provide a getter method only if you want the data field to be readable, and provide a setter method only if you want the data field to be updateable.
4. Clarity • [✓] Cohesion, consistency, and encapsulation are good guidelines for achieving design clarity. Additionally, a class should have a clear contract that is easy to explain and easy to understand. • [✓] Users can incorporate classes in many different combinations, orders, and environments. Therefore, you should design a class that imposes no restrictions on how or when the user can use it, design the properties in a way that lets the user set them in any order and with any combination of values, and design methods that function independently of their order of occurrence. • [✓] Methods should be defined intuitively without causing confusion. • [✓] You should not declare a data field that can be derived from other data fields.
5. Completeness • [✓] Classes are designed for use by many different customers. In order to be useful in a wide range of applications, a class should provide a variety of ways for customization through properties and methods.
6. Instance vs. Static • [✓] A variable or method that is dependent on a specific instance of the class must be an instance variable or method. A variable that is shared by all the instances of a class should be declared static. • [✓] Always reference static variables and methods from a class name (rather than a reference variable) to improve readability and avoid errors. • [✓] Do not pass a parameter from a constructor to initialize a static data field. It is better to use a setter method to change the static data field. • [✓] Instance and static are integral parts of object-oriented programming. A data field or method is either instance or static. Do not mistakenly overlook static data fields or methods. It is a common design error to define an instance method should have been static. • [✓] A constructor is always instance, because it is used to create a specific instance. A static variable or method can be invoked from an instance method, but an instance variable or method cannot be invoked from a static method.
7. Inheritance vs. Aggregation • [✓] The difference between inheritance and aggregation is the difference between an is-a and a has-a relationship.
8. Interfaces vs. Abstract Classes • [✓] Both interfaces and abstract classes can be used to specify common behavior for objects. How do you decide whether to use an interface or a class? In general, a strong is-a relationship that clearly describes a parentchild relationship should be modeled using classes. A weak is-a relationship, also known as an is-kind-of relationship, indicates that an object possesses a certain property. A weak is-a relationship can modeled using interfaces. • [✓] Interfaces are more flexible than abstract classes, because a subclass can extend only one superclass but can implement any number of interfaces. However, interfaces cannot contain concrete methods. The virtues of interfaces and abstract classes can be combined by creating an interface with an abstract class that implement it. Then you can use the interface or the abstract class, whichever is convenient.
Please choose 5 guidelines and discuss them in depth. For each guideline, use at least half a page for your discussion.
Hi, Please find the solution & Rate the answer.
Cohesion: Modern programmers have realized something called as a
"single responsibility principle". This concept is best understood
by an example. Lets say we have a class called FileOperations. It
makes a lot of sense to have all file related operations in that
single class only. Some methods in the file can be
"open","close","flush","save","saveCSVtoSpaceSeperated", where the
last method converts comma seperated values(for some reason) to
space seperated values. It would simply create havoc in the team,
if there was even another class which would handle, another set of
same kind of file operations.
Methods also need to have a single responsibility and not more.
Example, we can never expect a method named "open" doing more than
just returning a handle to a file on disk, or returning an error if
it was not possible to open that file.
Similarly, the work of "flush" method should only be, flush all the
data in the buffer to the HDD before closing the file. If the
methods would do anything more or less than what they are supposed
to, it would simply create havoc/confusion in the team.
Encapsulation: This is one of the most important principles of object oriented programming. When C language was invented, it was the procedure which was more important and not the data. Data was passed around according to the requirement of the methods. Slowly the flaws of such an approach were realized and software community moved to object oriented programming(OOP). In OOP, the object can decide how it reacts to the external environment. This is best understood by an example.
Lets say we have a variable which needs to keep track of number of passes issued at a gate. This means that, whenever a new object is created, that variable should not have a new instance of the same, which further means it should be static. Now we dont want it to get modified anywhere apart from the constructor of that object, where it is incremented every time a new object of that type is created. This means it should not be accessible outside the class. Hence, this variable needs to be private. We should also have a way of reading, how many passes were issued. Hence we need to have a getter method which simply returns the value of the object. This is the way of maintaining confidentiality of data in the program. Encapsulation makes sure what we can hide, and what we can show to the world. This is verily applicable in real life also.
Inheritance Vs Aggregation: Consider the following sentences:
"Car is a vehicle, Dog is an animal, Laptop is a computer". All
these are examples of "IS-A" relationships. Consider these
sentences: "Car has a tyre, car has a steering wheel, dog has
teeth, laptop has a processor". All these are examples of HAS-A
relationships. Here is a very important point. HAS-A relationships
tend to become member variables of the class for example, the car
class will have a variable called tyre, and it can be an array. All
the IS-A relationships tend to become child classes, example Car
class will become the child class of vehicle class where vehicle
class will have attributes which are common to all the vehicles,
like seating capacity. So a class called Vehicle HAS-A seating
capacity of "some number", otherwise there is no sense to any kind
of vehicle.
class Vehicle{
private float seatingCapacity;//assume setters and getters are
present as required
CapacityType type;
enum CapacityType{
LITRES,PERSONS,CC;//you can imagine
}
}
class Car extends Vehicle{//since car is a vehicle
public Car(){
setType(CapacityType.PERSONS)
//.. some other code
}
}
In the above Car is a vehicle and HAS-A seatingCapacity.
Interfaces vs Abstract classes:
As we know in Java we can Inherit from one class only, but there is
no limit to the number of interfaces a class can implement. This is
best explained by an example. Let's say we have an inheritance tree
called Animal and Vehicle in our program. There are many animals
and vehicles in the program. Let's say for example we have a method
called "run" which is present in both trees. If we come up with a
requirement in our program where we want to identify all the
objects in our program which can simply "run", instead of creating
an Abstract class and making Animal and Vehicle inherit it, it
would be better if objects which can run implement an interface
called "Runnable"(not java.lang.Runnable), which has a method
"run". Interface is a contract to what a class can do. If some
object implements an interface, it means it is capable of doing
that functionality. Where as an Abstract class is an IS-A
relationship. We should be very clear, when to use right concepts
for better maintenance of s/w for its lifetime. Otherwise, programs
don't remain maintainable.
Instance Vs Static: Instance variable is one which can have
different run time states for different objects, depending upon how
they are used by the program. On the contrary, static variable will
have only one different states depending upon all the variables of
all the objects created of the single Object. This is best
explained by an example.
class Bill{
int quantity;
int pricePerQuantity;//for simplicity.
static int billsPrinted;
public printBill(){
...
billsPrinted++;//adding to the number of bills printed
return;
}
}
In the above class, the number of bills printed depends upon the
number of times printBill method was called, it need not have a new
value per object of Bill type created in the program.
Completeness: Let's say we have a class called FileOperations which which has methods like below.
class FileOperations{
public Handle open(){
...
}
public Data read(){
...
}
public boolean write(String data){
...
}
...
}
In the above example, we can see that the write method can only
support String data, and what if the program needs to store images.
In the requirements collection phase and the design phase care
should be taken that classes are designed with Single
responsibility principle in mind, so that a class can meet complete
requirements of the software.
Get Answers For Free
Most questions answered within 1 hours.