State Pattern

This is an introduction to state pattern.

What is State Pattern

Allows an object to alter its behavior when its internal state changes.

Key Points

  1. An object has multiple states.
  2. State is a interface with some methods.
  3. Each specific state implements all method behaviors, includes state shifting.
  4. The object class will hold instance variables for all state types and a State type variable.
  5. Shared methods like setState or variables shared by all state are still in object class.
    • Each state class use object instance to access shared methods/variables.

Gumball Machine Example

Gumball machine has multiple states, all states has same methods(insertCoin, ejectCoin,
dispenseCoin…) but with different behaviors.

State Pattern Solution:

  • Define State interface to hold all diverse behaviors,
  • GumballMachine class
    • holds instance variable for all state class types and one State variable,
    • setState and gumball number variable/getGumballNumber are all in this class,
  • Implement each state class
    • state changes also happens inside these class,
    • GumballMachine instance is passed in to give us access to shared methods/variables.

My Code Example

https://github.com/AudreyMeng/Java/tree/master/StatePattern

Reference

Head First Design Pattern

Strategy Pattern

This is an introduction to Strategy Design Pattern.

What is Strategy Design Pattern

Concept

defines a family of algorithms,
encapsulates each one, and makes them interchangeable.
Strategy lets the algorithm vary independently from
clients that use it.

Key Points

  1. Base class extends to various child class type, children share/vary some behaviors
  2. For shared behaviors, implement in base class
  3. For varied for each typed class, implement in child class
  4. For behaviors some children share, some vary,
    • declare instance variables in base class,
    • interface types,
    • determine specific behaviors at runtime,
    • can change dynamically by set methods.

duck example

Requirements: a duck game with many kinds of different ducks.
Shared behaviors: swim
Behaviors varied each type: display
Behaviors some vary, some share: fly, quack

The first 2 kinds of behaviors are easy to handle:
shared swim: implement in base class
varied display: implement in each child class type.

The key is to design the 3rd kind of behavior.

Here is 3 different kinds of design:

inheritance

Implement fly/quack in base class as pic below, then all children type shares same behaviors. Not working!
Implement fly/quack in each child class, it works, but lots of duplicate code.
Inheritance Duck

interface

All child classes have to override fly/quack interface, tons of duplicate work.
Interface Duck

strategy pattern

Perfect way so far!
keep shared behaviors to reduce code work.
Instance variables from interfaces enables us to encapsulate just a couple of fly/quack behaviors to apply on all child classes.
Moreover, dynamic set methods in base class enable us dynamically change fly/quack behaviors.
Strategy Pattern Duck

My Code Example

https://github.com/AudreyMeng/Java/tree/master/StrategyPattern

Reference

Head First Design Pattern

Dynamic Filter Binding

What is Dynamic Filter Binding?

Bind filters to resource methods programmatically during the app initialization time.

Components

  1. Filter
  2. DynamicFeature
  3. Resource

Filter

  • implements ContainerRequestFilter, ContainerResponseFilter
  • override filter method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class LogFilter implements ContainerRequestFilter, ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext reqContext) throws IOException {
log(reqContext.getUriInfo(), reqContext.getHeaders());

}

@Override
public void filter(ContainerRequestContext reqContext,
ContainerResponseContext resContext) throws IOException {
log(reqContext.getUriInfo(), resContext.getHeaders());


}

private void log(UriInfo uriInfo, MultivaluedMap<String, ?> headers) {
System.out.println("Path: " + uriInfo.getPath());
headers.entrySet().forEach(h -> System.out.println(h.getKey() + ": " + h.getValue()));
}
}

DynamicFeature

  • @Provider
  • implements DynamicFeature
  • override configure to register filter (only works for path ‘/order’)
  • bind filter with resource
1
2
3
4
5
6
7
8
9
10
11
12
@Provider
public class FilterRegistrationFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (MyResource.class.isAssignableFrom(resourceInfo.getResourceClass())) {
Method method = resourceInfo.getResourceMethod();
if (method.getName().toLowerCase().contains("order")) {
context.register(new LogFilter());
}
}
}
}

Resource

Define path and verb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Path("")
public class MyResource {

@GET
@Path("customers")
public String getAllCustomers() {
System.out.println("in getAllCustomers()");
return "dummy-response for all customers";
}

@GET
@Path("customers/{id}")
public String getCustomerById(@PathParam("id") String id) {
System.out.println("in getCustomerById()");
return "dummy-response for customer " + id;
}

@GET
@Path("orders")
public String getOrders() {
System.out.println("in getOrders()");
return "dummy-response for orders";
}
}

References

https://www.logicbig.com/tutorials/java-ee-tutorial/jax-rs/filters-dynamic-binding.html

Introduction to Dropwizard

What is Dropwizard

Treat it as a library or a framework.
To provide implementations of everything a production-ready web application needs.

Components

  1. Application
  2. Configuration
  3. Representation
  4. Resource
  5. Health Check
    Dropwizard

Application

(HelloWorldApplication.java): startup the app.

1, static main is app’s entry point.
2, Register resource: in run method, 1,new resource instance 2,add to Jersey env.
3, read configuration from HelloWorldConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.helloworld;

public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
public static void main(String[] args) throws Exception {
new HelloWorldApplication().run(args);
}

@Override
public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
// configure aspects of the application required before the application is run
// like bundles, configuration source providers
}

@Override
public void run(HelloWorldConfiguration configuration,
Environment environment) {
final HelloWorldResource resource = new HelloWorldResource(
configuration.getTemplate(),
configuration.getDefaultName()
);
// REGISTER RESOURCE
environment.jersey().register(resource);
}

}

Configuration

(HelloWorldConfiguration.java): environment configuration.
Parameters are specified in a YAML configuration file.
Dropwizard parses the provided YAML configuration file and builds an instance of app configuration class by mapping YAML field names to object field names.

Representation

(Saying.java): API Data Structure.
Request content:

1
2
3
4
{
"id": 1,
"content": "Hi!"
}

Translate to representation class:
Jackson to serialize/deserialize @JsonProperty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.helloworld.api;

public class Saying {
private long id;
private String content;

public Saying(long id, String content) {
this.id = id;
this.content = content;
}

@JsonProperty
public long getId() {
return id;
}

@JsonProperty
public String getContent() {
return content;
}
}

Resource

(HelloWordResource.java): service implementation entry point
@Path (URI: /hello-world) and @Produces (Jersey’s content negotiation code: application/json)

request /hello-world?name=Dougie: sayHello method will be called with Optional.of("Dougie").

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.example.helloworld.resources;

@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
private final String defaultName;

public HelloWorldResource(String defaultName) {
this.defaultName = defaultName;
}

@GET
public Saying sayHello(@QueryParam("name") Optional<String> name) {
final String value = String.format(template, name.orElse(defaultName));
return new Saying(counter.incrementAndGet(), value);
}
}

Health Check

(TemplateHealthCheck.java): runtime tests that show if the app still works.

Bootstrap

Bootstrap is the the pre-start(temp) application environment, containing everything required to bootstrap a Dropwizard command.

Before a Dropwizard application can provide the command-line interface, parse a configuration file, it must first go through a bootstrapping phase.

This phase corresponds to initialize method. You can add Bundles, or register Jackson modules to include custom types as part of your configuration class.

Environments

A Dropwizard Environment consists of all the Resources, servlets, filters, Health Checks, Jersey providers, Managed Objects, Tasks, and Jersey properties.

Application class run method: where to create new resource instances, etc., and adding them to the given Environment class

Environment is a longer-lived object, holding Dropwizard’s Environment (not env. Such as dev or prod). It holds a similar, but somewhat different set of properties than the Bootsrap object.

References

http://www.dropwizard.io/en/stable/getting-started.html
https://xebia.com/blog/dropwizard/

Introduction to Guice

I hope to make this place my secret garden to track my technique growth.
This is my first post. Simple notes about Google Guice.

Guice Logo

What is Guice

The best resource is always the official website.

Think of Guice’s @Inject as the new new.
Guice can build the object graph.

Linked Bindings

Map a type to its implementation.

1
2
3
4
5
6
public class BillingModule extends AbstractModule {
@Override
protected void configure() {
bind(TransactionLog.class).to(DatabaseTransactionLog.class);
}
}

When you call injector.getInstance(TransactionLog.class), or when the injector encounters a dependency on TransactionLog, it will use a DatabaseTransactionLog.

@Provides Methods

To create an object. Must be defined within a module.

Scopes

By default, Guice returns a new instance each time it supplies a value.

@Singleton :to reuse instances for the lifetime of an application

Typical Example:

1
2
3
4
@Provides @Singleton
TransactionLog provideTransactionLog() {
...
}

Injections

Constructor Injection: annotate the constructor with the @Inject annotation
Method/Field Injection

Injection Example

A simple inject example:

https://github.com/AudreyMeng/Java/tree/master/guiceTest1

To @inject Communicator implementation field in Communication:

  1. guiceStart createInjector for BasicModule and getInstance ->

  2. BasicModule extends AbstractModule,

  3. in BasicModule.configure method binds Communicator to Communication ->

  4. Communication class @inject a Communicator

References

https://github.com/google/guice