5. Reorganize objects (data)

All objects processed in the program are data, and all abstractions and algorithms are for representing and processing data. Let's take a look at how to better organize data.

5.1 Self Encapsulate Field (self-encapsulate field)
If you directly access a field of this class in the same class, the coupling relationship with the field is very deep, establish a value/set value function for this field, and only use these functions. to access the field. Just like there is a principle "make all fields private as much as possible", in fact, even if variable fields are only accessed through getter/setter fields, there will be security risks unless protective copying and other means are used. On the issue of

" field access mode
", there are two distinct views: (1) In the class where the variable is defined, it can be freely accessed.
(2) Even in this class you should only use accessor indirection.
Personally support the first one, unless the value calculated by a certain algorithm , then the algorithm can be wrapped. Of course, the wise see wisdom.

5.2 Replace Data Value with Object
There is a data item that needs to be used together with other data and behaviors to make sense. The data item can be turned into an object to encapsulate the data and behavior.

Early in development, we often decide to represent simple situations with simple data items. However, as development progresses, these simple data items are no longer so simple. For example , a String might be used to represent "phone number" at first, but later Found out that special behavior like "formatting", "extracting area code" is required for phone numbers. This way the Duplicate Code and Feature Envy smells will soon emanate from the code. When these bad smells start to appear, it's time to talk about data values ​​becoming objects. It's an evolutionary process, and as requirements change, as organizations change, so too does the way our code is handled.

5.3 Change Value to Reference (change the value object to a reference object)
When many instances are derived from a class that are equal to each other, we want to replace them with the same object.

That is, create as few objects as possible. If multiple objects contain the same object (such as a Date), then references can be used instead of creating an object for each object. This can be achieved by using static factory methods or singleton pattern etc.

5.4 Replace Array with Object
If there is an array, the elements in it represent different things. Then you can use objects instead of arrays. For each element in the array becomes a field of the object.

I believe very few people will make this mistake. The elements of an array are generally data of the same category, otherwise the structure will be messy .

5.5 Duplicate Observed Data (duplicate "monitored data") For
example, if some domain data is placed in GUI controls, these domain data can be formed into an object separately, using the observer pattern. In this way, data and presentation can be decoupled, and the same data can be displayed in different ways. This is also based on a good hierarchical structure, which separates the business processing logic from the interface presentation layer.


5.6 Replace type code with subclasses
If there is a Immutable type code, and it affects the behavior of the class (acts differently depending on the value) . This type code can be replaced by a subclass.


Generally, the hallmark of such a situation is a conditional expression like switch . There may be two manifestations: a switch statement or an if-else construct. In either form, the type code value is checked and different actions are performed according to different values , which can be refactored by replacing conditional with polymorphism.
For smooth refactoring, the first thing to do is to replace the type code with an inheritance . Such an inheritance system should take the host class of the type code as the base class, and create a subclass for each type code. Then put different behaviors into corresponding subclasses, and choose different subtypes to perform different behaviors to replace the previous switch judgment.
But there are two cases where this cannot be done:
(1) The type code value has changed after the object is created.
(2) The typecode host class already has subclasses for other reasons. This requires the use of replace type code with State/Strategy. This is actually a choice between "inheritance and combination", and of course, combination is recommended. Special Note: Not all type codes need to be replaced whenever switch occurs. Only when the type code repeatedly determines the behavior of the class, and when the type code repeats to do different behaviors, it is necessary to refactor. After all, where judgment is required cannot be saved.



5.7 replace type code with State/Strategy (replacing type code with State/Strategy)
has a type code, which affects the behavior of the class, but it cannot be eliminated by inheritance, and the type code can also be replaced by a state object.


State mode and Strategy mode are very similar, so no matter which one you choose, the refactoring process is the same.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326996114&siteId=291194637