Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf1feb3f

Browse files
EdisonE3ohbus
andauthored
feature: Implement Presentation Model Pattern (iluwatar#1710)
*iluwatar#415 initial all componets*iluwatar#415 add src and tests*iluwatar#415 add diagram*iluwatar#415 add README*iluwatar#415 add README*iluwatar#415 change pom.xml*iluwatar#415 change pom.xml*iluwatar#415 change pom.xml*iluwatar#415 update pom.xml*iluwatar#415 change some code smell*iluwatar#415 change some code smell*iluwatar#415 update test*iluwatar#415 add javadoc*iluwatar#415 remove author tag*iluwatar#415 add lombok@AllArgsConstructor*iluwatar#415 fix code converge*iluwatar#415 fix code converge*iluwatar#415 fix code converge*iluwatar#415 add javadoc*iluwatar#415 fix code smell*iluwatar#415 fix code smell*iluwatar#415 add log information*iluwatar#415 remove unused import*iluwatar#415 add javadoc and more test*iluwatar#415 modify test*iluwatar#415 fix checkstyle*iluwatar#415 remove useless code and add more javadoc and test.*iluwatar#415 add package-info.java.*iluwatar#415 add package-info.java.*iluwatar#415 add more test.*iluwatar#415 fix code smell.*iluwatar#415 fix code smell and increase code coverage.*iluwatar#415 fix code smell.*iluwatar#415 update README.md*iluwatar#415 update README.md*iluwatar#415 make this demo better*iluwatar#415 satisfy checkstyle*iluwatar#415 make some field static.*iluwatar#415 make some fields static.*iluwatar#415 rename some fields static.* Delete package-info.javaCo-authored-by: Subhrodip Mohanta <subhrodipmohanta@gmail.com>
1 parent1388e38 commitf1feb3f

16 files changed

+1023
-0
lines changed

‎pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@
225225
<module>active-object</module>
226226
<module>model-view-viewmodel</module>
227227
<module>composite-entity</module>
228+
<module>presentation</module>
228229
</modules>
229230

230231
<repositories>

‎presentation/README.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
layout:pattern
3+
title:Presentation
4+
folder:presentation
5+
permalink:/patterns/presentation/
6+
categories:Behavioral
7+
tags:
8+
-Decoupling
9+
---
10+
##Also known as
11+
Application Model
12+
13+
##Intent
14+
Presentation Model pulls the state and behavior of the view out into a model class that is part of the presentation.
15+
16+
##Explanation
17+
18+
Real world example
19+
20+
>When we need to write a program with GUI, there is no need for us to put all presentation behavior in the view class. Because it will test become harder. So we can use Presentation Model Pattern to separate the behavior and view. The view only need to load the data and states from other class and show these data on the screen according to the states.
21+
22+
In plain words
23+
24+
>a pattern that used to divide the presentation and controlling.
25+
26+
Code Example
27+
28+
Class`view` is the GUI of albums. Methods`saveToPMod` and`loadFromPMod` are used to achieve synchronization.
29+
30+
```java
31+
publicclassView {
32+
/**
33+
* the model that controls this view.
34+
*/
35+
privatefinalPresentationModel model;
36+
37+
privateTextField txtTitle;
38+
privateTextField txtArtist;
39+
privateJCheckBox chkClassical;
40+
privateTextField txtComposer;
41+
privateJList<String> albumList;
42+
privateJButton apply;
43+
privateJButton cancel;
44+
45+
publicView() {
46+
model=newPresentationModel(PresentationModel.albumDataSet());
47+
}
48+
49+
/**
50+
* save the data to PresentationModel.
51+
*/
52+
publicvoidsaveToPMod() {
53+
LOGGER.info("Save data to PresentationModel");
54+
model.setArtist(txtArtist.getText());
55+
model.setTitle(txtTitle.getText());
56+
model.setIsClassical(chkClassical.isSelected());
57+
model.setComposer(txtComposer.getText());
58+
}
59+
60+
/**
61+
* load the data from PresentationModel.
62+
*/
63+
publicvoidloadFromPMod() {
64+
LOGGER.info("Load data from PresentationModel");
65+
txtArtist.setText(model.getArtist());
66+
txtTitle.setText(model.getTitle());
67+
chkClassical.setSelected(model.getIsClassical());
68+
txtComposer.setEditable(model.getIsClassical());
69+
txtComposer.setText(model.getComposer());
70+
}
71+
72+
publicvoidcreateView() {
73+
// the detail of GUI information like size, listenser and so on.
74+
}
75+
}
76+
```
77+
78+
Class`Album` is to store information of a album.
79+
80+
```java
81+
publicclassAlbum {
82+
83+
privateString title;
84+
privateString artist;
85+
privateboolean isClassical;
86+
/**
87+
* only when the album is classical,
88+
* composer can have content.
89+
*/
90+
privateString composer;
91+
}
92+
93+
```
94+
95+
Class`DisplatedAlbums` is store the information of all the albums that will be displayed on GUI.
96+
97+
```java
98+
publicclassDisplayedAlbums {
99+
privatefinalList<Album> albums;
100+
101+
publicDisplayedAlbums() {
102+
this.albums=newArrayList<>();
103+
}
104+
105+
publicvoidaddAlbums(finalStringtitle,
106+
finalStringartist,finalbooleanisClassical,
107+
finalStringcomposer) {
108+
if (isClassical) {
109+
this.albums.add(newAlbum(title, artist,true, composer));
110+
}else {
111+
this.albums.add(newAlbum(title, artist,false,""));
112+
}
113+
}
114+
}
115+
```
116+
117+
Class`PresentationMod` is used to control all the action of GUI.
118+
119+
```java
120+
publicclassPresentationModel {
121+
privatefinalDisplayedAlbums data;
122+
123+
privateint selectedAlbumNumber;
124+
privateAlbum selectedAlbum;
125+
126+
publicPresentationModel(finalDisplayedAlbumsdataOfAlbums) {
127+
this.data= dataOfAlbums;
128+
this.selectedAlbumNumber=1;
129+
this.selectedAlbum=this.data.getAlbums().get(0);
130+
}
131+
132+
/**
133+
* Changes the value of selectedAlbumNumber.
134+
*
135+
*@param albumNumber the number of album which is shown on the view.
136+
*/
137+
publicvoidsetSelectedAlbumNumber(finalintalbumNumber) {
138+
LOGGER.info("Change select number from {} to {}",
139+
this.selectedAlbumNumber, albumNumber);
140+
this.selectedAlbumNumber= albumNumber;
141+
this.selectedAlbum= data.getAlbums().get(this.selectedAlbumNumber-1);
142+
}
143+
144+
publicStringgetTitle() {
145+
return selectedAlbum.getTitle();
146+
}
147+
// other get methods are like this, which are used to get information of selected album.
148+
149+
publicvoidsetTitle(finalStringvalue) {
150+
LOGGER.info("Change album title from {} to {}",
151+
selectedAlbum.getTitle(), value);
152+
selectedAlbum.setTitle(value);
153+
}
154+
// other set methods are like this, which are used to get information of selected album.
155+
156+
/**
157+
* Gets a list of albums.
158+
*
159+
*@return the names of all the albums.
160+
*/
161+
publicString[]getAlbumList() {
162+
var result=newString[data.getAlbums().size()];
163+
for (var i=0; i< result.length; i++) {
164+
result[i]= data.getAlbums().get(i).getTitle();
165+
}
166+
return result;
167+
}
168+
}
169+
```
170+
171+
We can run class`App` to start this demo. the checkbox is the album classical; the first text field is the name of album artist; the second is the name of album title; the last one is the name of the composer:
172+
173+
![](./etc/result.png)
174+
175+
176+
##Class diagram
177+
![](./etc/presentation.urm.png"presentation model")
178+
179+
##Applicability
180+
Use the Presentation Model Pattern when
181+
182+
* Testing a presentation through a GUI window is often awkward, and in some cases impossible.
183+
* Do not determine which GUI will be used.
184+
185+
##Related patterns
186+
187+
-[Supervising Controller](https://martinfowler.com/eaaDev/SupervisingPresenter.html)
188+
-[Passive View](https://martinfowler.com/eaaDev/PassiveScreen.html)
189+
190+
##Credits
191+
192+
*[Presentation Model Patterns](https://martinfowler.com/eaaDev/PresentationModel.html)
193+

‎presentation/etc/presentation.urm.png

121 KB
Loading
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@startuml
2+
packagecom.iluwatar.presentation {
3+
classAlbum {
4+
~artist :String
5+
~composer :String
6+
~isClassical :boolean
7+
~rowId :int
8+
~title :String
9+
+Album(rowId : int, title : String, artist : String, isClassical : boolean, composer : String)
10+
}
11+
classApp {
12+
+App()
13+
+main(args : String[]) {static}
14+
}
15+
classDsAlbum {
16+
+albums : List<Album>
17+
+albumsCache : List<Album>
18+
+DsAlbum()
19+
+acceptChanges()
20+
+addAlbums(rowId : int, title : String, artist : String, isClassical : boolean, composer : String)
21+
}
22+
classPresentationMod {
23+
-data :DsAlbum
24+
-selectedAlbum :Album
25+
-selectedAlbumNumber :int
26+
+PresentationMod(data : DsAlbum)
27+
+albumDataSet() : DsAlbum {static}
28+
+getAlbumList() : String[]
29+
+getArtist() :String
30+
+getComposer() :String
31+
+getIsClassical() :boolean
32+
+getTitle() :String
33+
+setArtist(value : String)
34+
+setComposer(value : String)
35+
+setIsClassical(value : boolean)
36+
+setSelectedAlbumNumber(selectedAlbumNumber : int)
37+
+setTitle(value : String)
38+
}
39+
classView {
40+
~albumList : JList<String>
41+
~apply :JButton
42+
~cancel :JButton
43+
~chkClassical :JCheckBox
44+
~model :PresentationMod
45+
~notLoadView :boolean
46+
~txtArtist :TextField
47+
~txtComposer :TextField
48+
~txtTitle :TextField
49+
+View()
50+
+createView()
51+
+loadFromPMod()
52+
+saveToPMod()
53+
}
54+
}
55+
PresentationMod--> "-selectedAlbum"Album
56+
View--> "-model"PresentationMod
57+
DsAlbum--> "-albums"Album
58+
PresentationMod--> "-data"DsAlbum
59+
@enduml

‎presentation/etc/result.png

12.9 KB
Loading

‎presentation/pom.xml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<!--
2+
3+
The MIT License
4+
Copyright © 2014-2021 Ilkka Seppälä
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
24+
-->
25+
<projectxmlns="http://maven.apache.org/POM/4.0.0"
26+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
27+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
28+
<modelVersion>4.0.0</modelVersion>
29+
<parent>
30+
<groupId>com.iluwatar</groupId>
31+
<artifactId>java-design-patterns</artifactId>
32+
<version>1.25.0-SNAPSHOT</version>
33+
</parent>
34+
<artifactId>presentation</artifactId>
35+
<dependencies>
36+
<dependency>
37+
<groupId>org.junit.jupiter</groupId>
38+
<artifactId>junit-jupiter-engine</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
</dependencies>
42+
<build>
43+
<plugins>
44+
<!-- Maven assembly plugin is invoked with default setting which we have
45+
in parent pom and specifying the class having main method-->
46+
<plugin>
47+
<groupId>org.apache.maven.plugins</groupId>
48+
<artifactId>maven-assembly-plugin</artifactId>
49+
<executions>
50+
<execution>
51+
<configuration>
52+
<archive>
53+
<manifest>
54+
<mainClass>com.iluwatar.presentation.App</mainClass>
55+
</manifest>
56+
</archive>
57+
</configuration>
58+
</execution>
59+
</executions>
60+
</plugin>
61+
</plugins>
62+
</build>
63+
</project>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
packagecom.iluwatar.presentation;
2+
3+
importlombok.AllArgsConstructor;
4+
importlombok.Getter;
5+
importlombok.Setter;
6+
7+
/**
8+
*A class used to store the information of album.
9+
*/
10+
@Setter
11+
@Getter
12+
@AllArgsConstructor
13+
publicclassAlbum {
14+
/**
15+
* the title of the album.
16+
*/
17+
privateStringtitle;
18+
/**
19+
* the artist name of the album.
20+
*/
21+
privateStringartist;
22+
/**
23+
* is the album classical, true or false.
24+
*/
25+
privatebooleanisClassical;
26+
/**
27+
* only when the album is classical,
28+
* composer can have content.
29+
*/
30+
privateStringcomposer;
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
packagecom.iluwatar.presentation;
2+
3+
importlombok.extern.slf4j.Slf4j;
4+
5+
/**
6+
* The Presentation model pattern is used to divide the presentation and controlling.
7+
* This demo is a used to information of some albums with GUI.
8+
*/
9+
@Slf4j
10+
publicfinalclassApp {
11+
/**
12+
* the constructor.
13+
*/
14+
privateApp() {
15+
}
16+
17+
/**
18+
* main method.
19+
*
20+
* @param args args
21+
*/
22+
publicstaticvoidmain(finalString[]args) {
23+
varview =newView();
24+
view.createView();
25+
}
26+
}
27+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp