Skip to content

Commit afdeba4

Browse files
committed
iluwatar#355 finalize example
1 parent c229ec2 commit afdeba4

File tree

14 files changed

+573
-124
lines changed

14 files changed

+573
-124
lines changed

abstract-document/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,20 @@ tags:
1212
## Intent
1313
Achieve flexibility of untyped languages and keep the type-safety
1414

15-
![alt text](./etc/abstract-document_1.png "Abstract Document")
15+
![alt text](./etc/abstract-document-base.png "Abstract Document Base")
16+
17+
![alt text](./etc/abstract-document.png "Abstract Document Traits and Domain")
18+
1619

1720
## Applicability
1821
Use the Abstract Document Pattern when
1922

20-
* there is a need for dynamic properties
21-
* you want a better way to organize domain
22-
* you want loosely coupled system with flexibility of untyped languages
23+
* there is a need to add new properties on the fly
24+
* you want a flexible way to organize domain in tree like structure
25+
* you want more loosely coupled system
26+
2327

24-
## Real world examples
28+
## Credits
2529

26-
* [Speedment](https://github.com/speedment/speedment)
30+
* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
31+
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
* <p>
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
* <p>
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
* <p>
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.abstractdocument;
224

325
import java.util.List;
@@ -7,44 +29,44 @@
729
import java.util.function.Function;
830
import java.util.stream.Stream;
931

32+
/**
33+
* Abstract implementation of Document interface
34+
*/
1035
public abstract class AbstractDocument implements Document {
1136

12-
private final Map<String, Object> properties;
13-
14-
protected AbstractDocument(Map<String, Object> properties) {
15-
Objects.requireNonNull(properties, "properties map is required");
16-
this.properties = properties;
17-
}
18-
19-
@Override
20-
public Void put(String key, Object value) {
21-
properties.put(key, value);
22-
return null;
23-
}
24-
25-
@Override
26-
public Object get(String key) {
27-
return properties.get(key);
28-
}
29-
30-
@Override
31-
public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {
32-
Optional<List<Map<String, Object>>> any = Stream.of(get(key))
33-
.filter(el -> el != null)
34-
.map(el -> (List<Map<String, Object>>) el)
35-
.findAny();
36-
return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty();
37-
}
38-
39-
@Override
40-
public String toString() {
41-
StringBuilder builder = new StringBuilder();
42-
builder.append(getClass().getName()).append("[");
43-
properties.entrySet().forEach(e ->
44-
builder.append("[").append(e.getKey()).append(" : ").append(e.getValue()).append("]")
45-
);
46-
builder.append("]");
47-
return builder.toString();
48-
}
37+
private final Map<String, Object> properties;
38+
39+
protected AbstractDocument(Map<String, Object> properties) {
40+
Objects.requireNonNull(properties, "properties map is required");
41+
this.properties = properties;
42+
}
43+
44+
@Override
45+
public Void put(String key, Object value) {
46+
properties.put(key, value);
47+
return null;
48+
}
49+
50+
@Override
51+
public Object get(String key) {
52+
return properties.get(key);
53+
}
54+
55+
@Override
56+
public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {
57+
Optional<List<Map<String, Object>>> any = Stream.of(get(key)).filter(el -> el != null)
58+
.map(el -> (List<Map<String, Object>>) el).findAny();
59+
return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty();
60+
}
61+
62+
@Override
63+
public String toString() {
64+
StringBuilder builder = new StringBuilder();
65+
builder.append(getClass().getName()).append("[");
66+
properties.entrySet()
67+
.forEach(e -> builder.append("[").append(e.getKey()).append(" : ").append(e.getValue()).append("]"));
68+
builder.append("]");
69+
return builder.toString();
70+
}
4971

5072
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
* <p>
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
* <p>
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
* <p>
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.abstractdocument;
24+
25+
import com.iluwatar.abstractdocument.domain.Car;
26+
import com.iluwatar.abstractdocument.domain.HasModel;
27+
import com.iluwatar.abstractdocument.domain.HasParts;
28+
import com.iluwatar.abstractdocument.domain.HasPrice;
29+
import com.iluwatar.abstractdocument.domain.HasType;
30+
31+
import java.util.Arrays;
32+
import java.util.HashMap;
33+
import java.util.Map;
34+
35+
/**
36+
* The Abstract Document pattern enables handling additional, non-static
37+
* properties. This pattern uses concept of traits to enable type safety and
38+
* separate properties of different classes into set of interfaces.
39+
* <p>
40+
* <p>
41+
* In Abstract Document pattern,({@link AbstractDocument}) fully implements
42+
* {@link Document}) interface. Traits are then defined to enable access to
43+
* properties in usual, static way.
44+
*/
45+
public class App {
46+
47+
/**
48+
* Executes the App
49+
*/
50+
public App() {
51+
System.out.println("Constructing parts and car");
52+
53+
Map<String, Object> carProperties = new HashMap<>();
54+
carProperties.put(HasModel.PROPERTY, "300SL");
55+
carProperties.put(HasPrice.PROPERTY, 10000L);
56+
57+
Map<String, Object> wheelProperties = new HashMap<>();
58+
wheelProperties.put(HasType.PROPERTY, "wheel");
59+
wheelProperties.put(HasModel.PROPERTY, "15C");
60+
wheelProperties.put(HasPrice.PROPERTY, 100L);
61+
62+
Map<String, Object> doorProperties = new HashMap<>();
63+
doorProperties.put(HasType.PROPERTY, "door");
64+
doorProperties.put(HasModel.PROPERTY, "Lambo");
65+
doorProperties.put(HasPrice.PROPERTY, 300L);
66+
67+
carProperties.put(HasParts.PROPERTY, Arrays.asList(wheelProperties, doorProperties));
68+
69+
Car car = new Car(carProperties);
70+
71+
System.out.println("Here is our car:");
72+
System.out.println("-> model: " + car.getModel().get());
73+
System.out.println("-> price: " + car.getPrice().get());
74+
System.out.println("-> parts: ");
75+
car.getParts().forEach(p -> System.out
76+
.println("\t" + p.getType().get() + "/" + p.getModel().get() + "/" + p.getPrice().get()));
77+
}
78+
79+
/**
80+
* Program entry point
81+
*
82+
* @param args command line args
83+
*/
84+
public static void main(String[] args) {
85+
new App();
86+
}
87+
88+
}
Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,59 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
* <p>
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
* <p>
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
* <p>
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.abstractdocument;
224

325
import java.util.Map;
426
import java.util.function.Function;
527
import java.util.stream.Stream;
628

29+
/**
30+
* Document interface
31+
*/
732
public interface Document {
833

9-
/**
10-
* Puts the value related to the key
11-
*
12-
* @param key
13-
* @param value
14-
* @return Void
15-
*/
16-
Void put(String key, Object value);
34+
/**
35+
* Puts the value related to the key
36+
*
37+
* @param key element key
38+
* @param value element value
39+
* @return Void
40+
*/
41+
Void put(String key, Object value);
1742

18-
/**
19-
* Gets the value for the key
20-
*
21-
* @param key
22-
* @return value or null
23-
*/
24-
Object get(String key);
43+
/**
44+
* Gets the value for the key
45+
*
46+
* @param key element key
47+
* @return value or null
48+
*/
49+
Object get(String key);
2550

26-
/**
27-
* Gets the stream of child documents
28-
*
29-
* @param key
30-
* @param constructor
31-
* @return child documents
32-
*/
33-
<T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor);
51+
/**
52+
* Gets the stream of child documents
53+
*
54+
* @param key element key
55+
* @param constructor constructor of child class
56+
* @return child documents
57+
*/
58+
<T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor);
3459
}
Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,38 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
* <p>
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
* <p>
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
* <p>
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.abstractdocument.domain;
224

3-
import java.util.HashMap;
425
import java.util.Map;
526

627
import com.iluwatar.abstractdocument.AbstractDocument;
728

29+
/**
30+
* Car entity
31+
*/
832
public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {
933

10-
protected Car() {
11-
super(new HashMap<>());
12-
}
13-
14-
protected Car(Map<String,Object> properties) {
15-
super(properties);
16-
}
34+
public Car(Map<String, Object> properties) {
35+
super(properties);
36+
}
1737

1838
}

0 commit comments

Comments
 (0)