The pattern I'm aiming for is to put all the classes that I want clients to use - like model objects, interfaces and factories - in a "client" package and put the private implementation in an impl package that is inaccessible to clients.
I only want clients to access my API using interfaces and I want to prevent them from instantiating private implementation classes directly.
What follows is a simple example. It works but am wondering if there's a better way - I'd imagine that this is a commonly used pattern?
package client;
public interface Plant {
String getScientificName();
String getCommonName();
}
package client;
import impl.PlantImpl;
import java.util.function.BiFunction;
public final class PlantFactory {
private BiFunction<String, String, Plant> delegate;
public PlantFactory() {
PlantImpl.registerFactory(this);
}
public void setFactory(BiFunction<String, String, Plant> factory) {
delegate = factory;
}
public Plant newInstance(String scientificName, String commonName) {
return delegate.apply(scientificName, commonName);
}
}
package impl;
import client.Plant;
import client.PlantFactory;
import java.util.function.BiFunction;
public final class PlantImpl implements Plant {
private final String scientificName;
private final String commonName;
private PlantImpl(String scientificName, String commonName) {
this.scientificName = scientificName;
this.commonName = commonName;
}
#Override
public String getScientificName() {
return scientificName;
}
#Override
public String getCommonName() {
return commonName;
}
public static void registerFactory(PlantFactory plantFactory) {
plantFactory.setFactory(new Factory());
}
static class Factory implements BiFunction<String, String, Plant> {
#Override
public Plant apply(String scientificName, String commonName) {
return new PlantImpl(scientificName, commonName);
}
}
}
import client.Plant;
import client.PlantFactory;
public final class PlantViewer {
public static void main(String[] args) {
// Doesn't compile due to private constructor
// Plant wattle = new PlantImpl("Acacia longifolia", "Sydney Golden Wattle");
PlantFactory plantFactory = new PlantFactory();
Plant grevillea = plantFactory.newInstance("Grevillea caleyi", "Caley's Grevillea");
System.out.println("Plant name is " + grevillea.getCommonName());
}
}
Related
Help me in the following code and how to used the backup on the Hazelcast
migration of the hazelcast 3.x.x to 5.x.x
package com.hazelcast.map;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.HazelcastInstanceAware;
import com.hazelcast.nio.serialization.impl.BinaryInterface;
import java.util.Map;
// Interface AbstractEntryProcessor
#BinaryInterface
public abstract class AbstractEntryProcessor<K,V> implements EntryProcessor<K,V> {
private final EntryBackupProcessor<K,V> entryBackupProcessor;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
if (applyOnBackup) {
entryBackupProcessor = new EntryBackupProcessorImpl();
} else {
entryBackupProcessor = null;
}
}
//EntryBackupProcessor
#Override
public final EntryBackupProcessor getBackupProcessor() {
return entryBackupProcessor;
}
// class EntryBackupProcessorImpl
private class EntryBackupProcessorImpl implements EntryBackupProcessor<k,V>, HazelcastInstanceAware {
// generated for EntryBackupProcessorImpl which doesn't implement HazelcastInstanceAware
static final long serialVersionUID = -5081502753526394129L;
#Override
public void processBackup(Map.Entry<K,V> entry) {
process(entry);
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
final AbstractEntryProcessor<k,V> outer = AbstractEntryProcessor.this;
if (outer instanceof HazelcastInstanceAware) {
((HazelcastInstanceAware) outer).setHazelcastInstance(hazelcastInstance);
}
}
}
}
How to used the backup methods in 5.x.x versons of series
how to used the backup in the above question ?
This should work:
public abstract class AbstractEntryProcessor implements EntryProcessor, HazelcastInstanceAware {
protected transient HazelcastInstance hazelcastInstance;
private final boolean applyOnBackup;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
this.applyOnBackup = applyOnBackup;
}
//EntryBackupProcessor
#Override
public final EntryProcessor getBackupProcessor() {
if (!applyOnBackup || this instanceof ReadOnly) {
return null;
}
return this;
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
}
I am trying to design a framework for loading resources. So I have two options
Approach 1
Underlying structure: An interface with a simple abstract class implementation and more specific extends.
Access: static final members of class initialized to the class.
Approach 2
Underlying structure: A specific enum from the get go, implementing all interface methods: no leveraging partial implementations of abstract classes.
Access: as enum entries
While approach 1 is a lot more flexible and reusable, I like the way enums provide a clean usable list, ready to use as opposed to static finals with scope for Class.instance.instance.instance. ...
Is there a standard way to do this? Is there a better way to do this?
Though not strictly needed here's the code
Approach 1
Interface LoadableResource<T>
import java.util.ArrayDeque;
import java.util.Queue;
public interface LoadableResource<T> {
Queue<Exception> exceptionQueue=new ArrayDeque<>();
boolean load();//Load the resource and return status
boolean isLoaded() ;
T getResource();
void onLoadFail();
void onLoadSuccess();
void onException(Exception ex);
Queue<Exception> getExcpetions();
}
Abstract SimpleLoadableResource<T>
import java.util.Queue;
public abstract class SimpleLoadableResource<T> implements LoadableResource<T> {
private boolean FLAG_LOADED = false;
private T resource;
#Override
public boolean isLoaded() {
return FLAG_LOADED;
}
#Override
public T getResource() {
return resource;
}
#Override
public void onLoadFail() {}
#Override
public void onLoadSuccess() {}
#Override
public void onException(Exception ex) {exceptionQueue.add(ex); }
#Override
public Queue<Exception> getExcpetions() { return exceptionQueue; }
protected void setLoaded(boolean FLAG_LOADED) {
this.FLAG_LOADED = FLAG_LOADED;
}
public abstract T loader() throws Exception;
#Override
public boolean load() {
try {
resource=loader();
} catch (Exception e) { onException(e); }
if (isLoaded())
onLoadSuccess();
else
onLoadFail();
return isLoaded();
}
}
Specific SimpleLoadableImage
import javax.imageio.ImageIO;
import java.awt.*;
public class SimpleLoadableImage extends SimpleLoadableResource<Image>{
public static final SimpleLoadableImage LOGO1=new SimpleLoadableImage("1.jpg");
public static final SimpleLoadableImage LOGO2=new SimpleLoadableImage("2.jpg");
private final String path;
public SimpleLoadableImage(String path) {
this.path = path;
super.load();
}
#Override
public Image loader() throws Exception {
var res=ImageIO.read(this.getClass().getClassLoader().getResourceAsStream(path));
setLoaded(true);
return res;
}
}
Approach 2
import javax.imageio.ImageIO;
import java.awt.*;
import java.util.ArrayDeque;
import java.util.Queue;
public enum SimpleLoadableImage_Enum {
LOGO1("1.jpg"),
LOGO("2.jpg");
private final String path;
Queue<Exception> exceptionQueue=new ArrayDeque<>();
private boolean FLAG_LOADED = false;
private Image resource;
private SimpleLoadableImage_Enum(String path){
this.path=path;
try {
resource=ImageIO.read(this.getClass().getClassLoader().getResourceAsStream(path));
FLAG_LOADED=true;
} catch (Exception e) {
exceptionQueue.add(e);
}
}
public boolean isLoaded() { return FLAG_LOADED; }
public Image getResource() { return resource; }
public Queue<Exception> getExcpetions() { return exceptionQueue; }
}
public interface A extends C {
String getCh();
String getId();
String getReview();
}
public interface B extends C {
String getCh();
String getId();
String getReview();
}
#Data
#Builder
public class AImpl implements A{
private String ch;
private String id;
private String review;
}
#Data
#Builder
public class BImpl implements B{
private String ch;
private String id;
private String review;
}
so now to use the builders of these I do:
return AImpl.builder()
.ch("ch")
.id("id")
.review("somerview");
For B I do:
return BImpl.builder()
.ch("ch1")
.id("id1")
.review("some new review");
Is there a way where I can make this builder part into a function? I dont like the idea of repeating the same code again. Like where I can pass id channel and review in a function and I can the object?
Disclaimer: I have never really dealt with builders so there might be a really much better option :D
This approach writes builders for each interface individually.
This does require that the interfaces provide a setter method.
Using generics, the methods of the RootBuilder and BaseABuilder return an instance of the ImplABuilder so that the chain can continue properly.
This is a very simple implementation of the Thistype generic which in other languages exists by default. This implementation also relies on casting to the actual Thistype but if you set the generics properly, that shouldnt be an issue.
public class Test
{
public static void main(String[] args)
{
ImplA implA = ImplA
.builder()
.id("id")
.description("description")
.valueA("a")
.build();
}
}
public interface Root
{
String getId();
void setId(String id);
String getDescription();
void setDescription(String description);
}
public class RootBuilder<Thistype extends RootBuilder<Thistype, Instance>, Instance extends Root>
{
protected final Instance object;
RootBuilder(Instance object)
{
this.object = object;
}
public Thistype id(String value)
{
object.setId(value);
return (Thistype)this;
}
public Thistype description(String value)
{
object.setDescription(value);
return (Thistype)this;
}
public Instance build()
{
return object;
}
}
public interface BaseA extends Root
{
String getValueA();
void setValueA(String valueA);
}
public class BaseABuilder<Thistype extends BaseABuilder<Thistype, Instance>, Instance extends BaseA> extends RootBuilder<Thistype, Instance>
{
protected Instance object;
BaseABuilder(Instance object)
{
super(object);
}
public Thistype valueA(String value)
{
object.setValueA(value);
return (Thistype)this;
}
}
public interface BaseB extends Root
{
String getValueB();
void setValueB(String valueB);
}
public interface BaseC extends Root
{
String getValueC();
void setValueC(String valueC);
}
public final class ImplA implements BaseA
{
private String id;
private String description;
private String valueA;
private ImplA() { }
public static ImplABuilder builder()
{
return new ImplABuilder(new ImplA());
}
private static class ImplABuilder extends BaseABuilder<ImplABuilder, ImplA> // assuming ImplA is final
{
ImplABuilder(ImplA object)
{
super(object);
}
// additional methods for ImplA class
}
}
I'm working in a project that was implemented using Guice but we need to migrate it to Spring 3.x and we have this use-case below where beans need additional parameters for creation. How is this implemented in Spring? is it possible to implement using only annotations (and no xml)?
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.assistedinject.Assisted;
import javax.inject.Inject;
public class MyModule extends AbstractModule {
#Override
protected void configure() {
super.binder().install(new FactoryModuleBuilder().
implement(Car.class, CarImpl.class).
build(CarFactory.class));
}
}
public interface Car {
String getBrand();
String getModel();
}
public class CarImpl implements Car {
public CarImpl(#Assisted("brand") String brand, #Assisted("model") String model) {
this.brand = brand;
this.model = model;
}
#Override
String getBrand() { return brand; }
#Override
String getModel() { return model; }
private final String brand;
private final String model;
}
public interface CarFactory {
Car create(#Assisted("brand") String brand, #Assisted("model") String model);
}
public class Client {
#Inject CarFactory carFactory;
final Car myCar;
public Client() {
myCar = carFactory.create("BMW", "530d xDrive");
}
void driveIt() { /* don't crash it */ }
public static void main(String[] args) {
new Client().driveIt();
}
}
It looks like you just need a factory bean that returns a CarImpl.
public interface CarFactory {
Car create (String brand, String model);
}
#Bean
public CarFactory carFactory () {
return CarImpl::new;
}
I have a list of utilities that derive from:
abstract public class BaseUtil implements Callable{
public String name;
public StreamWrapper data;
public void setData(StreamWrapper stream){ this.data = stream; }
private static Class me = BaseUtil.class;
private static Method[] availableUtilities = me.getDeclaredMethods();
public static Method[] getUtilities(){ return availableUtilities; }
}
I want to, at each node, be able to assign a utility to it, something like:
Initialize(String utilName){
activeUtility = utilName;
gk = new GateKeeper(BaseUtil.getUtilities() <something>);
}
public class GateKeeper {
GateKeeper(BaseUtil util) {
this.util = util;
}
private BaseUtil util;
But I'm unsure on how to get the specific utility class from just the String passed in. An example utility is:
public class WordLengthUtil extends BaseUtil {
private String name = "WordLength";
public Integer call() {
System.out.println(this.data);
return Integer.valueOf(this.data.length());
}
}
You can use reflection:
String name = "WordLength";
String className = hashMap.get(name);
Callable plugin = (Callable) Class.forName(className).newInstance();
use HashMap to store binding between className and string identifier