|
6 | 6 | * [Chapter 3 - Functions](#chapter3)
|
7 | 7 | * [Chapter 4 - Comments](#chapter4)
|
8 | 8 | * [Chapter 5 - Formatting](#chapter5)
|
| 9 | +* [Chapter 6 - Objects and Data Structures](#chapter6) |
9 | 10 |
|
10 | 11 |
|
11 | 12 | <a name="chapter1">
|
@@ -831,3 +832,109 @@ Every programmer has his own favorite formatting rules, but if he works in a tea
|
831 | 832 |
|
832 | 833 | A team of developers should agree upon a single formatting style, and then every member of that team should use that style. We want the software to have a consistent style. We don't want it to appear to have been written by a bunch of disagreeing individuals.
|
833 | 834 |
|
| 835 | +<a name="chapter6"> |
| 836 | +## Chapter 6 - Objects and Data Structures |
| 837 | +</a> |
| 838 | +
|
| 839 | +### Data Abstraction |
| 840 | +
|
| 841 | +Hiding implementation is not just a matter of putting a layer of functions between the variables. Hiding implementation is about abstractions! A class does not simply push its variables out through getters and setters. Rather it exposes abstract interfaces that allow its users to manipulate the essence of the data, without having to know its implementation. |
| 842 | +
|
| 843 | +### Data/Object Anti-Symmetry |
| 844 | +
|
| 845 | +These two examples show the difference between objects and data structures. Objects hide their data behind abstractions and expose functions that operate on that data. Data structure expose their data and have no meaningful functions. |
| 846 | +
|
| 847 | +**Procedural Shape** |
| 848 | +```java |
| 849 | +public class Square { |
| 850 | + public Point topLeft; |
| 851 | + public double side; |
| 852 | +} |
| 853 | +
|
| 854 | +public class Rectangle { |
| 855 | + public Point topLeft; |
| 856 | + public double height; |
| 857 | + public double width; |
| 858 | +} |
| 859 | +
|
| 860 | +public class Circle { |
| 861 | + public Point center; |
| 862 | + public double radius; |
| 863 | +} |
| 864 | +
|
| 865 | +public class Geometry { |
| 866 | + public final double PI = 3.141592653589793; |
| 867 | +
|
| 868 | + public double area(Object shape) throws NoSuchShapeException { |
| 869 | + if (shape instanceof Square) { |
| 870 | + Square s = (Square)shape; |
| 871 | + return s.side * s.side; |
| 872 | + } |
| 873 | + else if (shape instanceof Rectangle) { Rectangle r = (Rectangle)shape; return r.height * r.width; |
| 874 | + } |
| 875 | + else if (shape instanceof Circle) { |
| 876 | + Circle c = (Circle)shape; |
| 877 | + return PI * c.radius * c.radius; |
| 878 | + } |
| 879 | + throw new NoSuchShapeException(); |
| 880 | + } |
| 881 | +} |
| 882 | +``` |
| 883 | +
|
| 884 | +**Polymorphic Shape** |
| 885 | +```java |
| 886 | +public class Square implements Shape { |
| 887 | + private Point topLeft; |
| 888 | + private double side; |
| 889 | + |
| 890 | + public double area() { |
| 891 | + return side*side; |
| 892 | + } |
| 893 | +} |
| 894 | +
|
| 895 | +public class Rectangle implements Shape { |
| 896 | + private Point topLeft; |
| 897 | + private double height; |
| 898 | + private double width; |
| 899 | +
|
| 900 | + public double area() { |
| 901 | + return height * width; |
| 902 | + } |
| 903 | +} |
| 904 | +
|
| 905 | +public class Circle implements Shape { |
| 906 | + private Point center; |
| 907 | + private double radius; |
| 908 | + public final double PI = 3.141592653589793; |
| 909 | +
|
| 910 | + public double area() { |
| 911 | + return PI * radius * radius; |
| 912 | + } |
| 913 | +} |
| 914 | +``` |
| 915 | +
|
| 916 | +Again, we see the complimentary nature of these two definitions; they are virtual opposites! This exposes the fundamental dichotomy between objects and data structures: |
| 917 | +
|
| 918 | +> Procedural code (code using data structures) makes it easy to add new functions without changing the existing data structures. OO code, on the other hand, makes it easy to add new classes without changing existing functions. |
| 919 | +
|
| 920 | +The complement is also true: |
| 921 | +
|
| 922 | +> Procedural code makes it hard to add new data structures because all the functions must change. OO code makes it hard to add new functions because all the classes must change. |
| 923 | +
|
| 924 | +Mature programmers know that the idea that everything is an object is a myth. Sometimes you really do want simple data structures with procedures operating on them. |
| 925 | +
|
| 926 | +### The Law of [Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter) |
| 927 | +
|
| 928 | +There is a well-known heuristic called the Law of Demeter2 that says a module should not know about the innards of the objects it manipulates. |
| 929 | +
|
| 930 | +More precisely, the Law of Demeter says that a method f of a class C should only call the methods of these: |
| 931 | +- C |
| 932 | +- An object created by f |
| 933 | +- An object passed as an argument to f |
| 934 | +- An object held in an instance variable of C |
| 935 | +
|
| 936 | +The method should not invoke methods on objects that are returned by any of the allowed functions. In other words, talk to friends, not to strangers. |
| 937 | +
|
| 938 | +### Data Transfer Objects |
| 939 | +
|
| 940 | +The quintessential form of a data structure is a class with public variables and no functions. This is sometimes called a data transfer object, or DTO. DTOs are very useful structures, especially when communicating with databases or parsing messages from sockets, and so on. They often become the first in a series of translation stages that convert raw data in a database into objects in the application code. |
0 commit comments