# Class Design Hints in Java

**Some hints that will make your classes more acceptable in well-mannered OOP circles:**


### 1. Always keep data private.

This is first and foremost; doing anything else violates **encapsulation**. You
may need to write an accessor or mutator method occasionally, but you are
still better off keeping the instance fields private. 


### 2.  Always initialize data.

Java won’t initialize local variables for you, but it will initialize instance
fields of objects. Don’t rely on the defaults, but initialize all variables
explicitly, either by supplying a default or by setting defaults in all
constructors.

### 3. Don’t use too many basic types in a class.

The idea is to replace multiple related uses of basic types with other
classes. This keeps your classes easier to understand and to change.

For example, replace the following instance fields in a **Customer** class:


```
private String street;
private String city;
private String state;
private int zip;
``` 

with a new class called **Address**. This way, you can easily cope with
changes to addresses, such as the need to deal with international addresses.



### 4. Not all fields need individual field accessors and mutators.

You may need to **get** and **set** an **employee’s salary**. But you certainly won’t
need to change the **hiring date** once the object is constructed. And, quite
often, objects have instance fields that you don’t want others to get or set,
such as an array of state abbreviations in an **Address** class.

### 5. Break up classes that have too many responsibilities.

This hint is, of course, vague: “too many” is obviously in the eye of the beholder. However, if there is an obvious way to break **one complicated class** into **two classes** that are conceptually **simpler**.
(On the other hand, don’t go overboard; ten classes, each with only one
method, are usually an overkill.)

Ex: Here is an example of a *bad design*


```
public class CardDeck // bad design
{
private int[] value;
private int[] suit;
public CardDeck() { . . . }
public void shuffle() { . . . }
public int getTopValue() { . . . }
public int getTopSuit() { . . . }
public void draw() { . . . }
}
``` 
This class really implements two separate concepts: a **deck of cards**, with its
**shuffle** and **draw** methods, and a **card**, with the methods to inspect its
**value** and **suit**. It makes sense to introduce a **Card** class that represents an
individual card. Now you have two classes, each with its own responsibilities:


```
public class CardDeck
{
private Card[] cards;
public CardDeck() { . . . }
public void shuffle() { . . . }
public Card getTop() { . . . }
public void draw() { . . . }
}

public class Card
{
private int value;
private int suit;
public Card(int aValue, int aSuit) { . . . }
public int getValue() { . . . }
public int getSuit() { . . . }
}
``` 



### 6. Make the names of your classes and methods reflect their responsibilities.

- Variables, methods and classes should have **meaningful names** that reflect what they represent
- Class name should be a **noun** (Ex: Order, Package,...)
- Accessor methods begin with a lowercase **get** (Ex: getSalary)
- Mutator methods use a lowercase **set** (Ex: setSalary)


### 7. Prefer immutable classes

- Problem with mutation is that it can happen concurrently when **multiple threads** try to **update an object at the same time**
- When classes are **immutable**, it is safe to share their objects **among multiple threads**
- Instead of mutating objects, we **create methods to return new objects** with the **modified state**
- Make class immutable whenever you can
- Of course, **not all classes should be immutable**. It would be strange to have the **raiseSalary** method return a new **Employee** object when an employee gets a raise.



(Source : Core Java Volumn I - Fundamentals).



