Top Banner
codecentric AG Dusan Zamurovic A pattern discussion
20

Meetup - Singleton & DI/IoC

Nov 22, 2014

Download

Software

Dusan Zamurovic

A discussion on Singleton and DI/IoC patterns.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Meetup - Singleton & DI/IoC

codecentric AG

Dusan Zamurovic

A pattern discussion

Page 2: Meetup - Singleton & DI/IoC

codecentric AG

- Singleton pattern- things we sometimes forget

- Dependency injection / Inversion of Control- Paired with Singleton- Example without third party library

TOPICS

Page 3: Meetup - Singleton & DI/IoC

codecentric AG

- What Singleton pattern does?- Implementation examples

- Wrong implementations- Implementations that look okay- Right implementations

Singleton

Page 4: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 01

public class Singleton01 { // TODO Make this class final?

private static Singleton01 instance = null;

private Singleton01() { // Private constructor prevents instantiation, // but also prevents sub-classing. }

public static Singleton01 getInstance() { if (instance == null) { instance = new Singleton01(); } return instance; }

}

Page 5: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 02

private static Singleton02 instance = null;

public static Singleton02 getInstance() { if (instance == null) { simulateMultiThreadEnvironment(); instance = new Singleton02(); }

return instance;}

// Not synchronized, not thread safe.

Page 6: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 03

private static Singleton03 instance = null; public synchronized static Singleton03 getInstance() { if (instance == null) { simulateMultiThreadEnvironment(); instance = new Singleton03(); }

return instance;}

// Synchronized, thread safe.

Page 7: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 04

private static Singleton04 instance = null;

public static Singleton04 getInstance() { if (instance == null) { synchronized (Singleton04.class) { simulateMultiThreadEnvironment(); instance = new Singleton04(); } } return instance;}

// Synchronized, performance optimization, not thread safe.

Page 8: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 05

private static Singleton05 instance = null;

public static Singleton05 getInstance() { if (instance == null) { synchronized (Singleton05.class) { if (instance == null) { instance = new Singleton05(); } } } return instance;}

// Double-checked locking – doesn’t work prior to Java 1.5.

Page 9: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 06

private static final Singleton06 INSTANCE = new Singleton06();

public static Singleton06 getInstance() { return INSTANCE;}

// Eager instantiating of the class. This works.

// What about serialization/deserialization?

Page 10: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 06 Serializable

public class Singleton06 implements Serializable {

private static final Singleton06 INSTANCE = new Singleton06();

public static Singleton06 getInstance() { return INSTANCE; }

}

protected Object readResolve() { return getInstance();}

Page 11: Meetup - Singleton & DI/IoC

codecentric AG

Singleton 07

public enum Singleton07 {

INSTANCE;

}

// What about serialization/deserialization?

// What about reflection?

Page 12: Meetup - Singleton & DI/IoC

codecentric AG

- What is DI / IoC?

- Implementation example- No third party library

Dependency Injection / Inversion of Control

Page 13: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Component {

}

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Inject {

}

// @Component is used to mark a class – a thing to inject.

// @Inject is used to mark a field – a place to inject.

Page 14: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

@Componentpublic class Controller {

@Inject private ManageCapable manager;

…}

@Componentpublic class Manager implements ManageCapable {

@Inject private Repository repository;

…}

Page 15: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

@Componentpublic class Repository {

public Resourcable save(Resourcable aResource) { // Here we "persist" the given resource // and return it like we really did it. return aResource; }}

Page 16: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

public class PackageScanner { …}

public class ClassScanner { …}

public class DependencyInjectionManager { …}

// https://github.com/dzamurovic/meetup_singleton.git

Page 17: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

public synchronized void run() throws Exception { if (initialized) { return; } // Find classes annotated with @Component. List<Class> components = packageScanner.findAnnotatedClasses( "rs.codecentric.meetup.diioc.example", Component.class);

// For each component... for (Class component : components) { Class definingClass = classScanner.getDefiningClass(component); // ... check if its instance already exists... if (!graph.containsKey(definingClass)) { // ... and instantiate it, if it doesn't. String className = component.getName(); graph.put(definingClass, Class.forName(component.getName()).newInstance()); } } }

Page 18: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

// For each object that is created... for (Iterator<Class> classIterator = graph.keySet().iterator(); classIterator.hasNext();) { Class definingClass = classIterator.next(); Object object = graph.get(definingClass);

// ... find dependencies it needs, ... for (Field f : classScanner.findAnnotatedFields(object.getClass(), Inject.class)) { if (!graph.containsKey(f.getType())) { // ... throw an error if a dependency cannot be satisfied, ... } // ... or set a value of the dependency. Object dependency = graph.get(f.getType()); f.set(object, dependency);

} }

initialized = true;

}

Page 19: Meetup - Singleton & DI/IoC

codecentric AG

Dependency Injection / Inversion of Control

public static void main(String args[]) throws Exception { final DependencyInjectionManager diManager = DependencyInjectionManager.getInstance();

Thread t1 = new DependencyInjectionThread("DI-thread-0", diManager); Thread t2 = …

t1.start(); t2.st…

t1.join(); t2.j…

diManager.describeDependencyGraph();}

Page 20: Meetup - Singleton & DI/IoC

codecentric AG

QUESTIONS?

https://github.com/dzamurovic/meetup_singleton.git

[email protected]

@ezamur

@CodingSerbia

http://www.meetup.com/Coding-Serbia/

www.codecentric.de

www.codecentric.rs

https://blog.codecentric.de

04/08/2023 20