├── LICENSE
├── README.md
├── pom.xml
└── src
└── main
└── java
└── com
└── haydikodlayalim
└── dpatterns
├── builder
├── BuilderRun.java
├── Product.java
└── ProductLombok.java
├── decorator
├── DecoratorRunner.java
├── IPhone.java
├── Iphone11.java
├── Iphone11Pro.java
├── Iphone11ProMax.java
├── NormalSample.java
├── Phone.java
└── PhoneDecorator.java
├── facade
├── AESEncryptor.java
├── CustomEncryptor.java
├── EncryptorFacade.java
├── MD5Encryptor.java
└── SHAEncryptor.java
├── factory
├── ExcelExporter.java
├── FileExporter.java
├── FileExporterFactory.java
├── PdfExporter.java
└── Run.java
└── singleton
├── BillPughSingleton.java
├── EagerInitializationSingleton.java
├── LazySingleton.java
├── Run.java
├── StaticBlockSingleton.java
└── ThreadSafeSingleton.java
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Haydi Kodlayalim
4 |
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 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-design-patterns
2 | Design Patterns - Java Implementations and Examples
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.haydikodlayalim
8 | java-design-patterns
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 1.8
13 |
14 |
15 |
16 |
17 | org.projectlombok
18 | lombok
19 | 1.18.12
20 |
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven.plugins
27 | maven-compiler-plugin
28 | 3.8.1
29 |
30 | 11
31 | 11
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/builder/BuilderRun.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.builder;
2 |
3 | public class BuilderRun {
4 | public static void main(String[] args) {
5 | Product product1 = new Product();
6 | product1.setId(12L);
7 | product1.setDescription("Description");
8 | product1.setName("Name");
9 |
10 | Product product2 = new Product.ProductBuilder()
11 | .id(12L)
12 | .name("Name")
13 | .description("Description")
14 | .build();
15 |
16 |
17 | ProductLombok lombokInstance = ProductLombok.builder()
18 | .id(12L)
19 | .name("Name")
20 | .description("Description")
21 | .build();
22 |
23 | System.out.println(product1);
24 | System.out.println(product2);
25 |
26 | System.out.println(lombokInstance);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/builder/Product.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.builder;
2 |
3 | import java.math.BigDecimal;
4 | import java.time.LocalDateTime;
5 |
6 | // POJO
7 | public class Product {
8 |
9 | private Long id;
10 | private String name;
11 | private LocalDateTime date;
12 | private Boolean inStock;
13 | private String description;
14 | private BigDecimal price;
15 |
16 | public Product() {
17 | }
18 |
19 | public Product(ProductBuilder builder) {
20 | this.id = builder.id;
21 | this.name = builder.name;
22 | this.date = builder.date;
23 | this.inStock = builder.inStock;
24 | this.description = builder.description;
25 | this.price = builder.price;
26 | }
27 |
28 | public Long getId() {
29 | return id;
30 | }
31 |
32 | public void setId(Long id) {
33 | this.id = id;
34 | }
35 |
36 | public String getName() {
37 | return name;
38 | }
39 |
40 | public void setName(String name) {
41 | this.name = name;
42 | }
43 |
44 | public LocalDateTime getDate() {
45 | return date;
46 | }
47 |
48 | public void setDate(LocalDateTime date) {
49 | this.date = date;
50 | }
51 |
52 | public Boolean getInStock() {
53 | return inStock;
54 | }
55 |
56 | public void setInStock(Boolean inStock) {
57 | this.inStock = inStock;
58 | }
59 |
60 | public String getDescription() {
61 | return description;
62 | }
63 |
64 | public void setDescription(String description) {
65 | this.description = description;
66 | }
67 |
68 | public BigDecimal getPrice() {
69 | return price;
70 | }
71 |
72 | public void setPrice(BigDecimal price) {
73 | this.price = price;
74 | }
75 |
76 | @Override
77 | public String toString() {
78 | return "Product{" +
79 | "id=" + id +
80 | ", name='" + name + '\'' +
81 | ", date=" + date +
82 | ", inStock=" + inStock +
83 | ", description='" + description + '\'' +
84 | ", price=" + price +
85 | '}';
86 | }
87 |
88 |
89 | public static class ProductBuilder {
90 | private Long id;
91 | private String name;
92 | private LocalDateTime date;
93 | private Boolean inStock;
94 | private String description;
95 | private BigDecimal price;
96 |
97 | public ProductBuilder id(Long id) {
98 | this.id = id;
99 | return this;
100 | }
101 |
102 | public ProductBuilder name(String name) {
103 | this.name = name;
104 | return this;
105 | }
106 |
107 | public ProductBuilder date(LocalDateTime date) {
108 | this.date = date;
109 | return this;
110 | }
111 |
112 | public ProductBuilder description(String description) {
113 | this.description = description;
114 | return this;
115 | }
116 |
117 | public ProductBuilder inStock(Boolean inStock) {
118 | this.inStock = inStock;
119 | return this;
120 | }
121 |
122 | public ProductBuilder price(BigDecimal price) {
123 | this.price = price;
124 | return this;
125 | }
126 |
127 | public Product build() {
128 | Product product = new Product(this);
129 | return product;
130 | }
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/builder/ProductLombok.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.builder;
2 |
3 | import java.math.BigDecimal;
4 | import java.time.LocalDateTime;
5 | import lombok.Builder;
6 |
7 | @Builder
8 | public class ProductLombok {
9 |
10 | private Long id;
11 | private String name;
12 | private LocalDateTime date;
13 | private Boolean inStock;
14 | private String description;
15 | private BigDecimal price;
16 |
17 | public Long getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Long id) {
22 | this.id = id;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | public LocalDateTime getDate() {
34 | return date;
35 | }
36 |
37 | public void setDate(LocalDateTime date) {
38 | this.date = date;
39 | }
40 |
41 | public Boolean getInStock() {
42 | return inStock;
43 | }
44 |
45 | public void setInStock(Boolean inStock) {
46 | this.inStock = inStock;
47 | }
48 |
49 | public String getDescription() {
50 | return description;
51 | }
52 |
53 | public void setDescription(String description) {
54 | this.description = description;
55 | }
56 |
57 | public BigDecimal getPrice() {
58 | return price;
59 | }
60 |
61 | public void setPrice(BigDecimal price) {
62 | this.price = price;
63 | }
64 |
65 | @Override
66 | public String toString() {
67 | return "ProductLombok{" +
68 | "id=" + id +
69 | ", name='" + name + '\'' +
70 | ", date=" + date +
71 | ", inStock=" + inStock +
72 | ", description='" + description + '\'' +
73 | ", price=" + price +
74 | '}';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/DecoratorRunner.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class DecoratorRunner {
4 |
5 | public static void main(String[] args) {
6 | Phone phone = new Iphone11ProMax(new IPhone());
7 |
8 | System.out.println(" Name : " + phone.getName());
9 | System.out.println(" Price : " + phone.getPrice());
10 | System.out.println(" Camera count : " + phone.cameraCount());
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/IPhone.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class IPhone implements Phone {
4 |
5 | @Override
6 | public String getName() {
7 | return "Iphone ";
8 | }
9 |
10 | @Override
11 | public int cameraCount() {
12 | return 2;
13 | }
14 |
15 | @Override
16 | public double getPrice() {
17 | return 699.90;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/Iphone11.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class Iphone11 extends PhoneDecorator {
4 |
5 | public Iphone11(IPhone basicPhone) {
6 | super(basicPhone);
7 | }
8 |
9 | @Override
10 | public String getName() {
11 | return super.getName() + " 11";
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/Iphone11Pro.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class Iphone11Pro extends PhoneDecorator {
4 |
5 | public Iphone11Pro(Phone basicPhone) {
6 | super(basicPhone);
7 | }
8 |
9 | @Override
10 | public double getPrice() {
11 | return basicPhone.getPrice() + 100;
12 | }
13 |
14 | @Override
15 | public String getName() {
16 | return basicPhone.getName() + "11 Pro";
17 | }
18 |
19 | @Override
20 | public int cameraCount() {
21 | return super.cameraCount() + 1 ;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/Iphone11ProMax.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class Iphone11ProMax extends Iphone11Pro {
4 | public Iphone11ProMax(Phone basicPhone) {
5 | super(basicPhone);
6 | }
7 |
8 | @Override
9 | public String getName() {
10 | return super.getName() + " Max ";
11 | }
12 |
13 | @Override
14 | public double getPrice() {
15 | return super.getPrice() + 100;
16 | }
17 |
18 | public String extraMethod() {
19 | return "Kirmizi ";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/NormalSample.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class NormalSample {
4 |
5 | public static class Iphone11 {
6 | public String name(){
7 | return "Iphone 11"; //100x100
8 | }
9 |
10 | int getCameraCount() {
11 | return 2;
12 | }
13 | }
14 |
15 | public static class Iphone11Pro {
16 |
17 | public String name(){
18 | return "Iphone 11 Pro"; //120x120
19 | }
20 |
21 | int getCameraCount() {
22 | return 3;
23 | }
24 | }
25 |
26 | public static class Iphone11Max {
27 |
28 | public String name(){
29 | return "Iphone 11 Pro Max"; //150x150
30 | }
31 |
32 | int getCameraCount() {
33 | return 3;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/Phone.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public interface Phone {
4 |
5 | String getName();
6 |
7 | int cameraCount();
8 |
9 | double getPrice();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/decorator/PhoneDecorator.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.decorator;
2 |
3 | public class PhoneDecorator implements Phone {
4 |
5 | protected Phone basicPhone;
6 |
7 | public PhoneDecorator(Phone basicPhone) {
8 | this.basicPhone = basicPhone;
9 | }
10 |
11 |
12 | @Override
13 | public String getName() {
14 | return basicPhone.getName();
15 | }
16 |
17 | @Override
18 | public int cameraCount() {
19 | return basicPhone.cameraCount();
20 | }
21 |
22 | @Override
23 | public double getPrice() {
24 | return basicPhone.getPrice();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/facade/AESEncryptor.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.facade;
2 |
3 |
4 | class AESEncryptor {
5 |
6 | public void encrypt(String text) {
7 | System.out.println("" + text + "");
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/facade/CustomEncryptor.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.facade;
2 |
3 | public class CustomEncryptor {
4 |
5 | public static void main(String[] args) {
6 | String text = "Content";
7 |
8 | AESEncryptor aesEncryptor = new AESEncryptor();
9 | aesEncryptor.encrypt(text);
10 |
11 | MD5Encryptor md5Encryptor = new MD5Encryptor();
12 | md5Encryptor.encrypt(text, "KEY");
13 |
14 | SHAEncryptor shaEncryptor = new SHAEncryptor();
15 | shaEncryptor.encrypt(text, "KEY", true);
16 |
17 | EncryptorFacade encryptorFacade = new EncryptorFacade();
18 | encryptorFacade.encrypt(text, EncryptorFacade.EncType.SHA);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/facade/EncryptorFacade.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.facade;
2 |
3 | public class EncryptorFacade {
4 |
5 | private AESEncryptor aesEncryptor = new AESEncryptor();
6 | private MD5Encryptor md5Encryptor = new MD5Encryptor();
7 | private SHAEncryptor shaEncryptor= new SHAEncryptor();
8 |
9 | public void encrypt(String text, EncType encType) {
10 | switch (encType) {
11 | case AES: aesEncryptor.encrypt(text); break;
12 | case MD5: md5Encryptor.encrypt(text, "KEY"); break;
13 | case SHA:shaEncryptor.encrypt(text, "KEY", true);
14 | default: throw new IllegalArgumentException(encType.toString());
15 | }
16 | }
17 |
18 | public enum EncType {
19 | SHA,
20 | MD5,
21 | AES
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/facade/MD5Encryptor.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.facade;
2 |
3 | class MD5Encryptor {
4 |
5 | public void encrypt(String text, String key) {
6 | System.out.println("" + text + key + "");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/facade/SHAEncryptor.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.facade;
2 |
3 | class SHAEncryptor {
4 |
5 | public void encrypt(String text, String key, boolean type) {
6 | if (type)
7 | System.out.println("" + text + key + "");
8 | else
9 | System.out.println("" + key + text + "");
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/factory/ExcelExporter.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.factory;
2 |
3 | class ExcelExporter implements FileExporter {
4 | @Override
5 | public String export(String content) {
6 | return "EXCEL -> " + content;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/factory/FileExporter.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.factory;
2 |
3 | public interface FileExporter {
4 |
5 | String export(String content);
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/factory/FileExporterFactory.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.factory;
2 |
3 | public class FileExporterFactory {
4 |
5 | public static FileExporter getInstance(FileType fileType){
6 | switch (fileType) {
7 | case EXCEL: return new ExcelExporter();
8 | case PDF:return new PdfExporter();
9 | default: throw new UnsupportedOperationException();
10 | }
11 | }
12 |
13 | public enum FileType {
14 | PDF,
15 | EXCEL;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/factory/PdfExporter.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.factory;
2 |
3 | class PdfExporter implements FileExporter {
4 | @Override
5 | public String export(String content) {
6 | return "PDF-> " + content;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/factory/Run.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.factory;
2 |
3 | public class Run {
4 | public static void main(String[] args) {
5 | String fileExcel = FileExporterFactory.getInstance(FileExporterFactory.FileType.EXCEL)
6 | .export(" Test content ");
7 | System.out.println(fileExcel);
8 |
9 | String filePdf = FileExporterFactory.getInstance(FileExporterFactory.FileType.EXCEL)
10 | .export(" Test content ");
11 | System.out.println(filePdf);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/BillPughSingleton.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class BillPughSingleton {
4 |
5 | private BillPughSingleton(){
6 |
7 | }
8 |
9 | public static BillPughSingleton getInstance() {
10 | return SingletonHelper.INSTANCE;
11 | }
12 |
13 | private static class SingletonHelper {
14 | private static final BillPughSingleton INSTANCE = new BillPughSingleton();
15 | }
16 |
17 | public void singletonTest(){
18 | System.out.println("BillPugh Singleton method calisti");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/EagerInitializationSingleton.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class EagerInitializationSingleton {
4 |
5 | private static final EagerInitializationSingleton INSTANCE = new EagerInitializationSingleton();
6 |
7 | private EagerInitializationSingleton(){
8 |
9 | }
10 |
11 | public static EagerInitializationSingleton getInstance(){
12 | return INSTANCE;
13 | }
14 |
15 | public void singletonTest(){
16 | System.out.println("Eager Singleton method calisti");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/LazySingleton.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class LazySingleton {
4 |
5 | private static LazySingleton lazySingleton;
6 |
7 | private LazySingleton(){
8 |
9 | }
10 |
11 | public static LazySingleton getLazySingleton() {
12 | if (lazySingleton == null)
13 | lazySingleton = new LazySingleton();
14 | return lazySingleton;
15 | }
16 |
17 | public void singletonTest(){
18 | System.out.println("Lazy Singleton method calisti");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/Run.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class Run {
4 | public static void main(String[] args) {
5 | EagerInitializationSingleton.getInstance().singletonTest();
6 |
7 | StaticBlockSingleton.getStaticBlockSingleton().singletonTest();
8 |
9 | LazySingleton.getLazySingleton().singletonTest();
10 |
11 | ThreadSafeSingleton.getThreadSafeSingleton().singletonTest();
12 |
13 | BillPughSingleton.getInstance().singletonTest();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/StaticBlockSingleton.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class StaticBlockSingleton {
4 |
5 | private static StaticBlockSingleton staticBlockSingleton;
6 |
7 | static {
8 | try {
9 | staticBlockSingleton = new StaticBlockSingleton();
10 | }catch (Exception e){
11 | }
12 | }
13 |
14 | private StaticBlockSingleton(){
15 |
16 | }
17 |
18 | public static StaticBlockSingleton getStaticBlockSingleton() {
19 | return staticBlockSingleton;
20 | }
21 |
22 | public void singletonTest(){
23 | System.out.println("Static Block Singleton method calisti");
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/haydikodlayalim/dpatterns/singleton/ThreadSafeSingleton.java:
--------------------------------------------------------------------------------
1 | package com.haydikodlayalim.dpatterns.singleton;
2 |
3 | public class ThreadSafeSingleton {
4 |
5 | private static ThreadSafeSingleton threadSafeSingleton;
6 |
7 | private ThreadSafeSingleton(){
8 |
9 | }
10 |
11 | public static synchronized ThreadSafeSingleton getThreadSafeSingleton() {
12 | if (threadSafeSingleton == null)
13 | threadSafeSingleton = new ThreadSafeSingleton();
14 | return threadSafeSingleton;
15 | }
16 |
17 | public void singletonTest(){
18 | System.out.println("ThreadSafe Singleton method calisti");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------