diff --git a/data-bus/README.md b/data-bus/README.md new file mode 100644 index 000000000..675e9fa3c --- /dev/null +++ b/data-bus/README.md @@ -0,0 +1,30 @@ +--- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ +layout: pattern # layout must allways be pattern +title: Data Bus # the properly formatted title +folder: data-bus # the folder name in which this pattern lies +permalink: /patterns/data-bus/ # the permalink to the pattern, to keep this uniform please stick to /patterns/FOLDER/ + +# both categories and tags are Yaml Lists +# you can either just pick one or write a list with '-'s +# usable categories and tags are listed here: https://github.com/iluwatar/java-design-patterns/blob/gh-pages/_config.yml +categories: creational # categories of the pattern +tags: # tags of the pattern + - best + - ever + - awesome +--- + +## Intent +Makes your code awesome + +![alt text](./etc/best_pattern.png "Best Pattern Ever") + +## Applicability +Use the Best Pattern Ever pattern when + +* you want to be the best +* you need to ... + +## Real world examples + +* [Nowhere](http://no.where.com) diff --git a/data-bus/src/main/java/com/iluwatar/databus/AbstractDataType.java b/data-bus/src/main/java/com/iluwatar/databus/AbstractDataType.java new file mode 100644 index 000000000..8926ce9aa --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/AbstractDataType.java @@ -0,0 +1,45 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Paul Campbell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package com.iluwatar.databus; + +/** + * . + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public class AbstractDataType implements DataType { + + private DataBus dataBus; + + @Override + public DataBus getDataBus() { + return dataBus; + } + + @Override + public void setDataBus(DataBus dataBus) { + this.dataBus = dataBus; + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/App.java b/data-bus/src/main/java/com/iluwatar/databus/App.java new file mode 100644 index 000000000..b76873cec --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/App.java @@ -0,0 +1,60 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus; + +import com.iluwatar.databus.data.StoppingData; +import com.iluwatar.databus.data.StartingData; +import com.iluwatar.databus.data.MessageData; +import com.iluwatar.databus.members.CounterMember; +import com.iluwatar.databus.members.StatusMember; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; + +/** + * The Data Bus pattern + *

+ *

{@see http://wiki.c2.com/?DataBusPattern}

+ * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@Slf4j +class App { + + public static void main(String[] args) { + final DataBus bus = DataBus.getInstance(); + bus.subscribe(new StatusMember(1)); + bus.subscribe(new StatusMember(2)); + final CounterMember foo = new CounterMember("Foo"); + final CounterMember bar = new CounterMember("Bar"); + bus.subscribe(foo); + bus.publish(StartingData.of(LocalDateTime.now())); + bus.publish(MessageData.of("Only Foo should see this")); + bus.subscribe(bar); + bus.publish(MessageData.of("Foo and Bar should see this")); + bus.unsubscribe(foo); + bus.publish(MessageData.of("Only Bar should see this")); + bus.publish(StoppingData.of(LocalDateTime.now())); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/DataBus.java b/data-bus/src/main/java/com/iluwatar/databus/DataBus.java new file mode 100644 index 000000000..edaefe623 --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/DataBus.java @@ -0,0 +1,73 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus; + +import java.util.HashSet; +import java.util.Set; + +/** + * The Data-Bus implementation. + * + *

This implementation uses a Singleton.

+ * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public class DataBus { + + private static final DataBus INSTANCE = new DataBus(); + + private final Set listeners = new HashSet<>(); + + public static DataBus getInstance() { + return INSTANCE; + } + + /** + * Register a member with the data-bus to start receiving events. + * + * @param member The member to register + */ + public void subscribe(final Member member) { + this.listeners.add(member); + } + + /** + * Deregister a member to stop receiving events. + * + * @param member The member to deregister + */ + public void unsubscribe(final Member member) { + this.listeners.remove(member); + } + + /** + * Publish and event to all members. + * + * @param event The event + */ + public void publish(final DataType event) { + event.setDataBus(this); + listeners.forEach(listener -> listener.accept(event)); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/DataType.java b/data-bus/src/main/java/com/iluwatar/databus/DataType.java new file mode 100644 index 000000000..e5729c19d --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/DataType.java @@ -0,0 +1,48 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Paul Campbell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package com.iluwatar.databus; + +/** + * Events are sent via the Data-Bus. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ + +public interface DataType { + + /** + * Returns the data-bus the event is being sent on. + * + * @return The data-bus + */ + DataBus getDataBus(); + + /** + * Set the data-bus the event will be sent on. + * + * @param dataBus The data-bus + */ + void setDataBus(DataBus dataBus); +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/Member.java b/data-bus/src/main/java/com/iluwatar/databus/Member.java new file mode 100644 index 000000000..d5ecb0152 --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/Member.java @@ -0,0 +1,37 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Paul Campbell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package com.iluwatar.databus; + +import java.util.function.Consumer; + +/** + * Members receive events from the Data-Bus. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public interface Member extends Consumer { + + void accept(DataType event); +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/data/MessageData.java b/data-bus/src/main/java/com/iluwatar/databus/data/MessageData.java new file mode 100644 index 000000000..2750b013e --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/data/MessageData.java @@ -0,0 +1,47 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus.data; + +import com.iluwatar.databus.AbstractDataType; +import com.iluwatar.databus.DataType; +import lombok.RequiredArgsConstructor; + +/** + * . + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@RequiredArgsConstructor +public class MessageData extends AbstractDataType { + + private final String message; + + public String getMessage() { + return message; + } + + public static DataType of(final String message) { + return new MessageData(message); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/data/StartingData.java b/data-bus/src/main/java/com/iluwatar/databus/data/StartingData.java new file mode 100644 index 000000000..f7159b77a --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/data/StartingData.java @@ -0,0 +1,49 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus.data; + +import com.iluwatar.databus.AbstractDataType; +import com.iluwatar.databus.DataType; +import lombok.RequiredArgsConstructor; + +import java.time.LocalDateTime; + +/** + * An event raised when applications starts, containing the start time of the application. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@RequiredArgsConstructor +public class StartingData extends AbstractDataType { + + private final LocalDateTime when; + + public LocalDateTime getWhen() { + return when; + } + + public static DataType of(final LocalDateTime when) { + return new StartingData(when); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/data/StoppingData.java b/data-bus/src/main/java/com/iluwatar/databus/data/StoppingData.java new file mode 100644 index 000000000..57918ec4c --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/data/StoppingData.java @@ -0,0 +1,49 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus.data; + +import com.iluwatar.databus.AbstractDataType; +import com.iluwatar.databus.DataType; +import lombok.RequiredArgsConstructor; + +import java.time.LocalDateTime; + +/** + * . + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@RequiredArgsConstructor +public class StoppingData extends AbstractDataType { + + private final LocalDateTime when; + + public LocalDateTime getWhen() { + return when; + } + + public static DataType of(final LocalDateTime when) { + return new StoppingData(when); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/members/CounterMember.java b/data-bus/src/main/java/com/iluwatar/databus/members/CounterMember.java new file mode 100644 index 000000000..45c90abb0 --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/members/CounterMember.java @@ -0,0 +1,53 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus.members; + +import com.iluwatar.databus.DataType; +import com.iluwatar.databus.Member; +import com.iluwatar.databus.data.MessageData; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * Receiver of Data-Bus events. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@Slf4j +@RequiredArgsConstructor +public class CounterMember implements Member { + + private final String name; + + @Override + public void accept(final DataType data) { + if (data instanceof MessageData) { + handleEvent((MessageData) data); + } + } + + private void handleEvent(MessageData data) { + log.info("{} sees message {}", name, data.getMessage()); + } +} diff --git a/data-bus/src/main/java/com/iluwatar/databus/members/StatusMember.java b/data-bus/src/main/java/com/iluwatar/databus/members/StatusMember.java new file mode 100644 index 000000000..5e1ca1656 --- /dev/null +++ b/data-bus/src/main/java/com/iluwatar/databus/members/StatusMember.java @@ -0,0 +1,63 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.databus.members; + +import com.iluwatar.databus.DataType; +import com.iluwatar.databus.Member; +import com.iluwatar.databus.data.MessageData; +import com.iluwatar.databus.data.StartingData; +import com.iluwatar.databus.data.StoppingData; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * Receiver of Data-Bus events. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@Slf4j +@RequiredArgsConstructor +public class StatusMember implements Member { + + private final int id; + + @Override + public void accept(final DataType data) { + if (data instanceof StartingData) { + handleEvent((StartingData) data); + } else if (data instanceof StoppingData) { + handleEvent((StoppingData) data); + } + } + + private void handleEvent(StartingData data) { + log.info("Receiver #{} sees application started at {}", id, data.getWhen()); + } + + private void handleEvent(StoppingData data) { + log.info("Receiver #{} sees application stopping at {}", id, data.getWhen()); + log.info("Receiver #{} sending goodbye message", id); + data.getDataBus().publish(MessageData.of(String.format("Goodbye cruel world from #%d!", id))); + } +} diff --git a/pom.xml b/pom.xml index 08477db20..4a474d091 100644 --- a/pom.xml +++ b/pom.xml @@ -467,4 +467,4 @@ - \ No newline at end of file +