This article series is written by the author (Java learning experience: about 2 years, Java work experience: a little) Created to understand "GoF Design Pattern 23". I intend to focus on the image rather than the accuracy, and I think that the content will be aimed at ** Java programming less than intermediate **.
If you can't reach it, please comment <(_ _)>
** Main learning sources: ** ・ "Introduction to Design Patterns Learned in the Augmented and Revised Java Language (written by Hiroshi Yuki)" ・ Design pattern | TECHSCORE
Design patterns to improve the quality of the program. In such a situation, it is a collection of wisdom of our ancestors, such as designing like this and helping later.
This article deals with 23 patterns known as ** "GoF Design Patterns" **.
"[GoF](https://ja.wikipedia.org/wiki/%E3%82%AE%E3%83%A3%E3%83%B3%E3%82%B0%E3%83%BB%E3%" 82% AA% E3% 83% 96% E3% 83% BB% E3% 83% 95% E3% 82% A9% E3% 83% BC_ (% E6% 83% 85% E5% A0% B1% E5% B7 It was advocated by a prominent group of software engineers called "% A5% E5% AD% A6))" and is one of the most famous design patterns.
Japanese version book: ** "Design pattern for reuse in object orientation" **
(I'm sorry I haven't read!)
There are various purposes. .. By learning GoF design patterns, you can expect the following advantages.
-Design patterns are useful for grouping program components by function or separating roles to create general parts.
-Java Collection (ArrayList, etc.) uses the Iterator pattern. Also, many use the Factory pattern for instantiation. -Some designs using design patterns are difficult to understand at first glance. If you don't know the pattern, you can't understand it by looking at the program, and you can misinterpret it as a complex and poor design.
-There are many object-oriented programming languages, not limited to Java. However, it is quite difficult to know how to use "object-oriented" well. .. (I don't think it's a very intuitive concept) I think that learning various patterns will help you to learn object-oriented programming.
・ GoF is a famous design pattern, and many engineers know it. Therefore, if you say, "This design is a" XXX pattern "", that may be enough to explain.
For those who are learning design patterns from now on, instead of just learning patterns There is a "purpose" for each pattern, and "GoF designs this for that purpose." I think that if you are aware of this point, you will be able to apply it.
It's a bonus. You can skip it.
Ease of making additions and modifications to the program. It also includes code readability and proper logging for analysis in the event of a problem. In terms of program design, it shows "flexibility" that can respond to situations such as function additions and specification changes.
-If the parts are organized for each function / role in the program, the visibility of the program will be improved and maintainability will be improved. -Even if each part is modified, maintainability will improve if it is made so that it does not affect the surroundings.
Ease of reuse of programs and their parts. You can use one part in multiple places in the program, or you can use it in another program with some modifications. In addition to reducing the trouble of writing the same code twice The quality of parts that have passed the rigorous test phase should be guaranteed. If quality-guaranteed parts can be reused as they are, the test man-hours can be reduced.
-Parts with "general design" that do not depend on special conditions are highly reusable. -It can be said that the official language APIs are extremely reusable.
A "good" program that is highly maintainable and reusable -It is "organized" for each function / role, making it easy to modify and add functions. -There are many "general-made" parts that are separated as much as possible from the special circumstances in the program.
However, because the program is for solving a real concrete problem, You have to write "concrete" processing and values somewhere.
** Considering the circumstances around that, the GoF design pattern often designs as follows. ** **
・ By subdividing, the work in charge of each part becomes clear. ・ The range of influence when replacing or modifying parts is reduced.
-Use interfaces and abstract classes to determine the relationships between parts. ・ Leave the specific processing to an ordinary class (concrete class). This makes it easier to replace the concrete class.
・ Do not write specific descriptions such as which concrete class to new () here and there. Let an expert manage it, for example the main function. Then, you can switch between various concrete classes by modifying only main ().
-By reducing the dependency between parts or collecting them in a specific place The range of influence when modifying parts can be reduced.
・ Maintain the independence of parts by showing only the necessary parts to the user side -It is also possible to combine multiple parts into one large part. In that case, hide the parts other than the parts for the window.
The parts of the program are closely related to other parts.
A common problem when you want to modify a program Modifying one part "A" may require (possibly) modify another part "B" as well. At this time, "B" is said to be ** "dependent" ** on "A".
In Java, when the name of class "A" appears in the description of class "B", "B" depends on "A". For example, if you rename the "A" to "New A", you will have to change all the "A" that appear in the "B" to "New A". Otherwise, the compiler will get angry.
It is unlikely that you will actually change only the name, but as long as you bother to describe class "A" in class "B", "B" means that "A" is used in some way. (There can be various situations such as using an instance or inheriting it.) If you rewrite the description in "A" in this state, there is a possibility that the function of "B" using "A" will be affected in some way.
On the contrary, no matter how much modification is made to class "B", it does not affect the class "A" side. (When "A" does not use "B") From within the code for class "A", you wouldn't even be able to see if "B" exists in the first place. Therefore, it can be said that class "A" does not depend on class "B".
When the dependence between parts becomes complicated, the independence of parts is lost and the time and effort required for correction increases. Therefore, the dependencies should be designed to be as small as possible and easy to control.
Preventing a specific part of a program part from being seen or touched from the outside is called ** "concealment" **. "Hiding" the right part is called ** "encapsulation" **.
For example, let's say you have a stove here. There is a power ON / OFF button on the top of the stove, and when you press it, a warm breeze comes out. The inside of the machine is covered with a cover, and parts such as heaters and fans moving inside cannot be seen or touched. This is the "encapsulated" state, and the parts that are unnecessary for the user are "hidden".
What if the stove cover is removed and the mechanical parts are completely visible? You can't find the power button at a glance, but you can see the heater, fan, screws, and other internal parts. It's very difficult to understand where to operate. It is possible that you may inadvertently touch an important part and break the stove. This is the state where it is not "hidden".
In this way, proper concealment has two advantages. -The user only needs to check the window for using parts (power button, etc.), which makes it easier to handle. ・ Protects the internal elements of parts from unexpected changes from the outside
In Java, hiding is mainly achieved by using ** access control ** such as private and public.