Skip to content

Instantly share code, notes, and snippets.

@IamCostello
Created March 28, 2020 15:20
Show Gist options
  • Select an option

  • Save IamCostello/b4c1d5860da50005c8167ea94fea26f4 to your computer and use it in GitHub Desktop.

Select an option

Save IamCostello/b4c1d5860da50005c8167ea94fea26f4 to your computer and use it in GitHub Desktop.
Observer pattern in practice using PropertyChange
package com.company;
class Consumer{
private Repository repository;
public Consumer(Repository repository){
this.repository = repository;
}
public void consume(){
System.out.println("Consumed: ");
repository.getProducts().forEach(System.out::println);
repository.getProducts().clear();
}
}
package com.company;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class ConsumerObserver implements PropertyChangeListener {
private RepositoryObservable repository;
public ConsumerObserver(RepositoryObservable repository){
this.repository = repository;
}
public void propertyChange(PropertyChangeEvent propertyChangeEvent){
if(propertyChangeEvent.getPropertyName() == "hasProducts"){
System.out.println("Consumed: ");
repository.getProducts().forEach(System.out::println);
repository.getProducts().clear();
}
}
}
package com.company;
public class Main {
public static void main(String[] args) throws InterruptedException {
Repository repository = new Repository();
Manufacturer manufacturer = new Manufacturer(repository);
Manufacturer manufacturer2 = new Manufacturer(repository);
Consumer consumer = new Consumer(repository);
repository.addManufacturer(manufacturer);
repository.addManufacturer(manufacturer2);
repository.addConsumer(consumer);
while(true){
if(repository.hasSpace()){
repository.notifyManufacturers();
}
if(repository.hasProducts()){
repository.notifyConsumers();
}
Thread.sleep(1000);
}
}
}
package com.company;
public class Main {
public static void main(String[] args) throws InterruptedException {
RepositoryObservable repository = new RepositoryObservable();
ManufacturerObserver manufacturer = new ManufacturerObserver(repository);
ManufacturerObserver manufacturer2 = new ManufacturerObserver(repository);
ConsumerObserver consumer = new ConsumerObserver(repository);
repository.addManufacturer(manufacturer);
repository.addManufacturer(manufacturer2);
repository.addConsumer(consumer);
repository.addPropertyChangeListener(manufacturer);
repository.addPropertyChangeListener(manufacturer2);
repository.addPropertyChangeListener(consumer);
while(true){
if(repository.hasSpace())
if(repository.hasProducts())
Thread.sleep(1000);
}
}
}
package com.company;
class Manufacturer {
static private int product = 0;
private Repository repository;
public Manufacturer(Repository repository){
this.repository = repository;
}
public void produce(){
System.out.println("Produced: " + product);
repository.addProduct(product);
product++;
}
}
package com.company;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class ManufacturerObserver implements PropertyChangeListener {
static private int product = 0;
private RepositoryObservable repository;
public ManufacturerObserver(RepositoryObservable repository){
this.repository = repository;
}
public void propertyChange(PropertyChangeEvent propertyChangeEvent){
if(propertyChangeEvent.getPropertyName() == "hasSpace"){
System.out.println("Produced: " + product);
repository.addProduct(product);
product++;
}
}
}
package com.company;
import java.util.ArrayList;
import java.util.List;
class Repository {
private List<Integer> products = new ArrayList<>(10);
private List<Consumer> consumers = new ArrayList<>();
private List<Manufacturer> manufacturers = new ArrayList<>();
public void addConsumer(Consumer consumer){
consumers.add(consumer);
}
public void addManufacturer(Manufacturer manufacturer){
manufacturers.add(manufacturer);
}
public List<Integer> getProducts() {
return products;
}
public void addProduct(int id){
if(hasSpace()){
products.add(id);
}
}
public boolean hasSpace(){
return products.size() < 10;
}
public boolean hasProducts(){
return !products.isEmpty();
}
public void notifyManufacturers(){
for(Manufacturer manufacturer: manufacturers){
manufacturer.produce();
}
}
public void notifyConsumers(){
for(Consumer consumer : consumers){
consumer.consume();
}
}
}
package com.company;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
public class RepositoryObservable {
private List<Integer> products = new ArrayList<>(10);
private List<ConsumerObserver> consumers = new ArrayList<>();
private List<ManufacturerObserver> manufacturers = new ArrayList<>();
private PropertyChangeSupport notify;
public RepositoryObservable(){
notify = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener){
notify.addPropertyChangeListener(propertyChangeListener);
}
public void addConsumer(ConsumerObserver consumer){
consumers.add(consumer);
}
public void addManufacturer(ManufacturerObserver manufacturer){
manufacturers.add(manufacturer);
}
public List<Integer> getProducts() {
return products;
}
public void addProduct(int id){
if(products.size() < 10){
products.add(id);
}
}
public boolean hasSpace(){
boolean state = products.size() < 10;
notify.firePropertyChange("hasSpace", false, state);
return state;
}
public boolean hasProducts(){
boolean state = !products.isEmpty();
notify.firePropertyChange("hasProducts", false, state);
return state;
}
}
@IamCostello
Copy link
Author

  1. Poprzez użycie interfejsu jak w powyższym przykładzie lub zawarcie obu klas w klasie nadrzędnej.
  2. Wprowadzenie kolekcji lub zawarcie magazynów w klasie nadrzędnej.
  3. Konsument i Producent nie ma na siebie wpływu, komunikują się tylko z klasą Magazyn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment