Minimize the accessibility of classes and members

Assignment Help Programming Languages
Reference no: EM13304805

Why is this correct/when is this the right idea? (Which should include some summary of the idea, but briefly!)

When could (or is) this wrong or a bad idea? Note: "Never" is an acceptable answer but requires explanation.

example how to answer the two questions

Item 13

First question answer.

Second question answer.

- Item 14

Minimize the accessibility of classes and members

The single most important factor that distinguishes a well-designed module from a poorly designed one is the degree to which the module hides its internal data and other implementation details from other modules. A well-designed module hides all of its implementation details, cleanly separating its API from its implementa- tion. Modules then communicate only through their APIs and are oblivious to each others' inner workings. This concept, known as information hiding or encap- sulation, is one of the fundamental tenets of software design [Parnas72].

Information hiding is important for many reasons, most of which stem from the fact that it decouples the modules that comprise a system, allowing them to be developed, tested, optimized, used, understood, and modified in isolation. This speeds up system development because modules can be developed in parallel. It eases the burden of maintenance because modules can be understood more quickly and debugged with little fear of harming other modules. While informa- tion hiding does not, in and of itself, cause good performance, it enables effective performance tuning: once a system is complete and profiling has determined which modules are causing performance problems (Item 55), those modules can be optimized without affecting the correctness of other modules. Information hid- ing increases software reuse because modules that aren't tightly coupled often prove useful in other contexts besides the ones for which they were developed.

CLASSES AND INTERFACES

Finally, information hiding decreases the risk in building large systems, because individual modules may prove successful even if the system does not.

Java has many facilities to aid in information hiding. The access control mecha- nism [JLS, 6.6] specifies the accessibility of classes, interfaces, and members. The accessibility of an entity is determined by the location of its declaration and by which, if any, of the access modifiers (private, protected, and public) is present on the declaration. Proper use of these modifiers is essential to information hiding.

The rule of thumb is simple: make each class or member as inaccessible as possible. In other words, use the lowest possible access level consistent with the proper functioning of the software that you are writing.

For top-level (non-nested) classes and interfaces, there are only two possible access levels: package-private and public. If you declare a top-level class or inter- face with the public modifier, it will be public; otherwise, it will be package-pri- vate. If a top-level class or interface can be made package-private, it should be. By making it package-private, you make it part of the implementation rather than the exported API, and you can modify it, replace it, or eliminate it in a subsequent release without fear of harming existing clients. If you make it public, you are obligated to support it forever to maintain compatibility.

If a package-private top-level class (or interface) is used by only one class, consider making the top-level class a private nested class of the sole class that uses it (Item 22). This reduces its accessibility from all the classes in its package to the one class that uses it. But it is far more important to reduce the accessibility of a gratuitously public class than of a package-private top-level class: the public class is part of the package's API, while the package-private top-level class is already part of its implementation.

For members (fields, methods, nested classes, and nested interfaces), there are four possible access levels, listed here in order of increasing accessibility:

• private-The member is accessible only from the top-level class where it is declared.

• package-private-The member is accessible from any class in the package where it is declared. Technically known as default access, this is the access lev- el you get if no access modifier is specified.

• protected-The member is accessible from subclasses of the class where it is declared (subject to a few restrictions [JLS, 6.6.2]) and from any class in the package where it is declared.

• public-The member is accessible from anywhere.

ITEM 13: MINIMIZE THE ACCESSIBILITY OF CLASSES AND MEMBERS 69

After carefully designing your class's public API, your reflex should be to make all other members private. Only if another class in the same package really needs to access a member should you remove the private modifier, making the member package-private. If you find yourself doing this often, you should reex- amine the design of your system to see if another decomposition might yield classes that are better decoupled from one another. That said, both private and package-private members are part of a class's implementation and do not normally impact its exported API. These fields can, however, "leak" into the exported API if the class implements Serializable (Item 74, Item 75).

For members of public classes, a huge increase in accessibility occurs when the access level goes from package-private to protected. A protected member is part of the class's exported API and must be supported forever. Also, a protected member of an exported class represents a public commitment to an implementa- tion detail (Item 17). The need for protected members should be relatively rare.

There is one rule that restricts your ability to reduce the accessibility of meth- ods. If a method overrides a superclass method, it is not permitted to have a lower access level in the subclass than it does in the superclass [JLS, 8.4.8.3]. This is necessary to ensure that an instance of the subclass is usable anywhere that an instance of the superclass is usable. If you violate this rule, the compiler will gen- erate an error message when you try to compile the subclass. A special case of this rule is that if a class implements an interface, all of the class methods that are also present in the interface must be declared public. This is so because all members of an interface are implicitly public [JLS, 9.1.5].

To facilitate testing, you may be tempted to make a class, interface, or mem- ber more accessible. This is fine up to a point. It is acceptable to make a private member of a public class package-private in order to test it, but it is not acceptable to raise the accessibility any higher than that. In other words, it is not acceptable to make a class, interface, or member a part of a package's exported API to facilitate testing. Luckily, it isn't necessary either, as tests can be made to run as part of the package being tested, thus gaining access to its package-private elements.

Instance fields should never be public (Item 14). If an instance field is non- final, or is a final reference to a mutable object, then by making the field public, you give up the ability to limit the values that can be stored in the field. This means you also give up the ability to enforce invariants involving the field. Also, you give up the ability to take any action when the field is modified, so classes with public mutable fields are not thread-safe. Even if a field is final and refers to an immutable object, by making the field public you give up the flexibility to switch to a new internal data representation in which the field does not exist.

CLASSES AND INTERFACES

The same advice applies to static fields, with the one exception. You can expose constants via public static final fields, assuming the constants form an inte- gral part of the abstraction provided by the class. By convention, such fields have names consisting of capital letters, with words separated by underscores (Item 56). It is critical that these fields contain either primitive values or references to immutable objects (Item 15). A final field containing a reference to a mutable object has all the disadvantages of a nonfinal field. While the reference cannot be modified, the referenced object can be modified-with disastrous results.

Note that a nonzero-length array is always mutable, so it is wrong for a class to have a public static final array field, or an accessor that returns such a field. If a class has such a field or accessor, clients will be able to modify the con- tents of the array. This is a frequent source of security holes:

// Potential security hole!
public static final Thing[] VALUES = { ... };

Beware of the fact that many IDEs generate accessors that return references to pri- vate array fields, resulting in exactly this problem. There are two ways to fix the problem. You can make the public array private and add a public immutable list:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
Alternatively, you can make the array private and add a public method that returns a copy of a private array:
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}

To choose between these alternatives, think about what the client is likely to do with the result. Which return type will be more convenient? Which will give bet- ter performance?

To summarize, you should always reduce accessibility as much as possible. After carefully designing a minimal public API, you should prevent any stray classes, interfaces, or members from becoming a part of the API. With the excep- tion of public static final fields, public classes should have no public fields. Ensure that objects referenced by public static final fields are immutable.

-------------------
Item 14: Eliminate obsolete object references

When you switch from a language with manual memory management, such as C or C++, to a garbage-collected language, your job as a programmer is made much easier by the fact that your objects are automatically reclaimed when you're through with them. It seems almost like magic when you first experience it. It can easily lead to the impression that you don't have to think about memory manage- ment, but this isn't quite true.

Consider the following simple stack implementation:

// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
} }
There's nothing obviously wrong with this program (but see Item 26 for a generic version). You could test it exhaustively, and it would pass every test with flying colors, but there's a problem lurking. Loosely speaking, the program has a "memory leak," which can silently manifest itself as reduced performance due to

ELIMINATE OBSOLETE OBJECT REFERENCES

increased garbage collector activity or increased memory footprint. In extreme cases, such memory leaks can cause disk paging and even program failure with an OutOfMemoryError, but such failures are relatively rare.

So where is the memory leak? If a stack grows and then shrinks, the objects that were popped off the stack will not be garbage collected, even if the program using the stack has no more references to them. This is because the stack main- tains obsolete references to these objects. An obsolete reference is simply a refer- ence that will never be dereferenced again. In this case, any references outside of the "active portion" of the element array are obsolete. The active portion consists of the elements whose index is less than size.

Memory leaks in garbage-collected languages (more properly known as unin- tentional object retentions) are insidious. If an object reference is unintentionally retained, not only is that object excluded from garbage collection, but so too are any objects referenced by that object, and so on. Even if only a few object refer- ences are unintentionally retained, many, many objects may be prevented from being garbage collected, with potentially large effects on performance.

The fix for this sort of problem is simple: null out references once they become obsolete. In the case of our Stack class, the reference to an item becomes obsolete as soon as it's popped off the stack. The corrected version of the pop method looks like this:

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference return result;
}

An added benefit of nulling out obsolete references is that, if they are subse- quently dereferenced by mistake, the program will immediately fail with a NullPointerException, rather than quietly doing the wrong thing. It is always beneficial to detect programming errors as quickly as possible.

When programmers are first stung by this problem, they may overcompensate by nulling out every object reference as soon as the program is finished using it. This is neither necessary nor desirable, as it clutters up the program unnecessarily. Nulling out object references should be the exception rather than the norm. The best way to eliminate an obsolete reference is to let the variable that contained the reference fall out of scope. This occurs naturally if you define each variable in the narrowest possible scope (Item 45).

CREATING AND DESTROYING OBJECTS

So when should you null out a reference? What aspect of the Stack class makes it susceptible to memory leaks? Simply put, it manages its own memory. The storage pool consists of the elements of the elements array (the object refer- ence cells, not the objects themselves). The elements in the active portion of the array (as defined earlier) are allocated, and those in the remainder of the array are free. The garbage collector has no way of knowing this; to the garbage collector, all of the object references in the elements array are equally valid. Only the pro- grammer knows that the inactive portion of the array is unimportant. The pro- grammer effectively communicates this fact to the garbage collector by manually nulling out array elements as soon as they become part of the inactive portion.

Generally speaking, whenever a class manages its own memory, the pro- grammer should be alert for memory leaks. Whenever an element is freed, any object references contained in the element should be nulled out.

Another common source of memory leaks is caches. Once you put an object reference into a cache, it's easy to forget that it's there and leave it in the cache long after it becomes irrelevant. There are several solutions to this problem. If you're lucky enough to implement a cache for which an entry is relevant exactly so long as there are references to its key outside of the cache, represent the cache as a WeakHashMap; entries will be removed automatically after they become obso- lete. Remember that WeakHashMap is useful only if the desired lifetime of cache entries is determined by external references to the key, not the value.

More commonly, the useful lifetime of a cache entry is less well defined, with entries becoming less valuable over time. Under these circumstances, the cache should occasionally be cleansed of entries that have fallen into disuse. This can be done by a background thread (perhaps a Timer or ScheduledThreadPoolExecu- tor) or as a side effect of adding new entries to the cache. The LinkedHashMap class facilitates the latter approach with its removeEldestEntry method. For more sophisticated caches, you may need to use java.lang.ref directly.

A third common source of memory leaks is listeners and other callbacks.

If you implement an API where clients register callbacks but don't deregister them explicitly, they will accumulate unless you take some action. The best way to ensure that callbacks are garbage collected promptly is to store only weak refer- ences to them, for instance, by storing them only as keys in a WeakHashMap.

Because memory leaks typically do not manifest themselves as obvious fail- ures, they may remain present in a system for years. They are typically discovered only as a result of careful code inspection or with the aid of a debugging tool known as a heap profiler. Therefore, it is very desirable to learn to anticipate prob- lems like this before they occur and prevent them from happening.

Reference no: EM13304805

Questions Cloud

How far was the face standing from the mirror : A face appears in a convex mirror; face is 75% its normal size and appears to be 24cm behind the mirror. How far was the face standing from the mirror
What are your monthly car payments : You are considering buying a new car. the sticker price is $15,000 and you have $2,000 to put toward a down payment. If you can negotiate a nominal annual interest rate of 10% and you wish to pay for the car over a 5 year period, what are your mon..
Determine what is the minimum standard size that is needed : a mountain water reservoir in a national park is to provide water at a flow rate of Q= 200 gpm and a minimum pressure of 40 psig in the lodge of the valley 200 ft below the reservoir.
What is elevation of b by neglecting curvature and reaction : The line of sight of a level falls at a rate if 0.122ft/ 100 ft when the level bubble is centered. A backsight of 4.782 is taken on point A, which is at 75 ft from the level. the elevation of a is 425.238 ft.
Minimize the accessibility of classes and members : Why is this correct/when is this the right idea and Minimize the accessibility of classes and members
What sales volume would be required in order to meet : The investors will put up the funds if the project is likely to have an operating income of $500,000 or more. What sales volume would be required in order to meet the minimum profit goal? (Hint: Use the breakeven formula, but include the required ..
Calculate the effective cost of both proposals : Calculate the effective cost of both proposals, and indicate which proposal should be accepted.
Calculate the velocity and flow rate of acetone at the exit : A tank containing acetone at 20 oC has a drain pipe connected vertically at the bottom. The pipe is made of galvanized iron, 0.5 in NPS Schedule 40 with length L= 2m. The acetone depth in the tank is H= 5 m.
Determine the critical point tc and the critical do : If the critical point in a DO sag curve is found to be 18km downstream from the discharge point of untreated wastewater, would you expect the critical point to move upstream (toward the discharge point)

Reviews

Write a Review

Programming Languages Questions & Answers

  Create classes for account and savingsaccount

Create and write three classes - Account, CheckingAccount, and SavingsAccount. Have CheckingAccount and SavingsAccount inherit from Account.

  Write program to calculate distance and time hurricane take

Write C++ program that will calculate the distance and time it will take (days/hours) for hurricane to reach Ft. Lauderdale if: Hurricane is at coordinates 16 N, 64 W, just SE of South Fla. off in Atlantic, with a speed of 20 mph.

  Identify all the pure-strategy nash equilibria of game

Identify all of the pure-strategy Nash Equilibria of this game. Identify at least one mixed-strategy Nash Equilibrium, and show that it is a Nash Equilibrium.

  Write application to simulate coin tossing

Write an application that simulates coin tossing. Let the program toss the coin each time the user presses the "Toss" button. Count the number of times each side of the coin appears.

  Design program which models worms behavior

Design a program that models the worms behavior in the following scenario: A worm is moving toward an apple. Each time it moves, the worm cuts the distance between itself and the apple.

  Explain a script namedmyfind.sh that performs a subset

Write a script namedmyfind.sh that performs a subset of the find command. Your script must handle the following options:-name, -type, -newer, -maxdepth, -mindepth, and-exec

  Write program which demands user to enter ten numbers

Write the program which demands user to enter 10 numbers (using an input box) and prints (using a message box) message ‘negative' if number is less than zero.

  Program to generate a random number between a range

Write down a program to generate random number between 1 and 100 and asks user to guess what number is.

  Write program to read data for employee and print name

Write a program which reads data for employee and prints name and salary of employee. Data read is: Name. Number of hours worked.

  Program by bernstein-s conditions to get maximum parallelism

Restructure program by using Bernstein's conditions in order to get maximum parallelism between processes. Specify which of the three conditions is not satisfied.

  Hierarchy of processes

Write a program that creates a hierarchy of processes using the fork() system call.

  Write down a method which is passed string argument

Write down a method, getFirstLine, which is passed a String argument and that returns first line. (Recall that lines are terminated with the "n" character.)

Free Assignment Quote

Assured A++ Grade

Get guaranteed satisfaction & time on delivery in every assignment order you paid with us! We ensure premium quality solution document along with free turntin report!

All rights reserved! Copyrights ©2019-2020 ExpertsMind IT Educational Pvt Ltd