I'm trying to build a customer email generator in java using the abstract factory pattern. I understand how to use the factory method pattern; however, I'm a bit confused about the abstract factory pattern. I'm trying to generate an email based on customer type. Could you look at my code below and tell me if I'm using the abstract method correctly? Thank you
public abstract class EmailTemplate {
public abstract String getHeader();
public abstract String getBody();
public abstract String getFooter();
public String generateEmail(){
return getHeader()+"\n"+getBody()+"\n"+getFooter();
}
}
public interface EmailFactory {
EmailTemplate createEmail();
}
public class BusinessEmail extends EmailTemplate {
#Override
public String getHeader() {
return "Dear [business customer],";
}
#Override
public String getBody() {
return "Thank you for being our valued customer. We are so grateful for the pleasure of serving you and hope we met your expectations.";
}
#Override
public String getFooter() {
return "Best Regards," +
"[name]";
}
}
public interface EmailGeneratorFactory {
EmailTemplate createEmail();
}
public class BusinessFactory implements EmailGeneratorFactory {
#Override
public EmailTemplate createEmail() {
return new BusinessEmail();
}
}
public class EMailGenerationSystem {
private static EMailGenerationSystem EMailGenerationSystem = new EMailGenerationSystem();
private EMailGenerationSystem(){};
public static EMailGenerationSystem getInstance(){
return EMailGenerationSystem;
}
public EmailTemplate getEmail(EmailGeneratorFactory factory){
return factory.createEmail();
}
}
Related
Background
I learned Factory pattern, and the power of generics and I'm attempting to piece them together.
Here are my efforts
Without generic input parameter - No warnings
public abstract class ArtifactCreator {
public abstract void setArtifacts(String workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(String input) {
return null;
}
}
public class BarArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(String input) {
return null;
}
}
public class Factory {
public ArtifactCreator getArtifactCreator(String domain) {
if (domain == "foo") {
return new FooArtifactCreator()
} else if (domain == "bar") {
return new BarArtifactCreator()
}
return null;
}
}
My whole problem is the workflowInput is relegated to the type String. But I want it to be some generic POJO.
With generics - I get warnings in Factory.java and Store.java that I want to get rid of correctly. (I want to be using generics for my use-case the right way).
Raw use of parameterized class 'ArtifactCreator' on both the files in Store.java and Factory.java
Unchecked call to 'setArtifacts(T)' as a member of raw type 'ArtifactCreator' in Store.java
public abstract class ArtifactCreator {
public abstract void setArtifacts(T workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator<FooInput> {
#Override
public void setArtifacts(FooInput input) {
return null;
}
}
public class BarArtifactCreator extends ArtifactCreator<BarInput> {
#Override
public void setArtifacts(BarInput input) {
return null;
}
}
public class Factory {
public ArtifactCreator getArtifactCreator(String domain) {
if (domain == "foo") {
return new FooArtifactCreator()
} else if (domain == "bar") {
return new BarArtifactCreator()
}
return null;
}
}
public class Input {
private String domain;
private String otherInput;
}
public class Store {
private final Factory factory;
public Store(Factory factory) {
this.factory = factory;
}
public ArtifactCreator getCaseClosureArtifactFactory(Input req) {
ArtifactCreator artifactCreator = factory.setArtifacts(req.getDomain());
//In reality - Create either FooInput or BarInput depending on
//`otherInput` field in `Input` POJO. Assume that there will be another
//factory/HashMap to return the input needed
FooInput input = new FooInput();
artifactCreator.setArtifacts(input);
}
}
One way I can think of solving my problems is do something like:
public class WorkflowInput {
private FooInput input;
private BarInput input;
}
public abstract class ArtifactCreator {
public abstract void setArtifacts(WorkflowInput workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(WorkflowInput input) {
FooInput input = input.getFooInput(); //Extract specific input
}
}
public class BarArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(WorkflowInput input) {
BarInput input = input.getBarInput(); //Extract specific input
}
}
This feels a bit unecessary to keep some fields in WorkflowInput null.
I was wondering how can I return a concrete implementation given a variable as argument in a function.
This is my test code
public interface Items {
String getName();
}
public class Car implements Items{
#Override
public String getName() {
return "Car";
}
public void drive(){
//To something
}
}
public class Shelf implements Items{
#Override
public String getName() {
return "Shelf";
}
public String getBooks(String bookName){
return bookName;
}
}
public enum Item {
CAR(Service::getCar),
TABLE(Service::getShelf),
;
Function<Service, ? extends Items> serviceFunction;
Item(Function<Service, ? extends Items> serviceFunction) {
this.serviceFunction = serviceFunction;
}
}
public class Service {
public Car getCar(){
return new Car();
}
public Shelf getShelf(){
return new Shelf();
}
public Items getItem(Item item){
return item.serviceFunction.apply(this);
}
public static void main(String[] args) {
Service service = new Service();
service.getItem(Item.CAR).getName();
// service.getItem(Item.CAR).drive(); // This is not valid.
}
}
So what I want is based on that enum I should be able to execute a set of functions related to that enum without passing the implementation identifier itself.
I know I can do this. And I will work but I was thinking of getting the concrete implementation without passing Class<T> klass.
public <T extends Items> T getItem(Item item, Class<T> klass){
return (T) item.serviceFunction.apply(this);
}
public static void main(String[] args) {
Service service = new Service();
service.getItem(Item.CAR, Car.class).drive();
}
How to access parent class's methods from child class? Following is my class implementation:
public interface BaseUrl {
public String getNameSpace();
public String getUrl();
}
BaseSoapUrl Class:
public class BaseSoapUrl implements BaseUrl {
#Override
public String getNameSpace() {
return "https://host.com/AndroidWFC/";
}
#Override
public String getUrl() {
return "https://host.com/AndroidWFC/MobileWS.asmx";
}
}
SoapURL Interface:
public interface SoapURL {
public String getSoapAction();
public String getMethodName();
}
LoginSoap Class:
public class LoginSoap extends BaseSoapUrl implements SoapURL {
#Override
public String getSoapAction() {
return "https://host.com/AndroidWFC/UserControl";
}
#Override
public String getMethodName() {
return "UserControl";
}
}
For the sake of simplifying the code i want to implement them like this. earlier it was something like below :
public interface SoapURL {
public String getNameSpace();
public String getUrl();
public String getSoapAction();
public String getMethodName();
}
LoginSoap Class:
public class LoginSoap implements SoapURL {
#Override
public String getNameSpace() {
return "https://host.com/AndroidWFC/";
}
#Override
public String getUrl() {
return "https://host.com/AndroidWFC/MobileWS.asmx";
}
#Override
public String getSoapAction() {
return "https://host.com/AndroidWFC/UserControl";
}
#Override
public String getMethodName() {
return "UserControl";
}
}
and i could access these methods like below :
private SoapURL soapURL = new LoginSoap();
String static final url = soapURL.getUrl();
Now the return values form public String getNameSpace(); and public String getUrl(); are going to be same in all child classes ; so why to write code again and again. There are going to be many classes which is going to implements SoapURL interface because of web service is being used.
so my question is how to access methods which is in BaseSoapUrl through soapURL?
You can re-factor the SoapURL interface to be an abstract class, where you can provide some common implementation of the getNameSpace() and getUrl() methods and leave the others as abstract ones, so that the sub-classes will be forced to provide implementation for them.
public abstract class SoapURL {
public String getNameSpace() {
return "https://host.com/AndroidWFC/";
}
public String getUrl() {
return "https://host.com/AndroidWFC/MobileWS.asmx";
}
public abstract String getSoapAction();
public abstract String getMethodName();
}
I think your refactoring was not correct. If you consider that a SoapUrl must have a getNameSpace(), then define the getNameSpace() method in the interface.
If the purpose of your refactoring was to always return the same values for some of the SoapUrl's methods, I would suggest to follow this organization:
public interface SoapUrl {
String getNameSpace();
String getUrl();
String getSoapAction();
String getMethodName();
}
public abstract class BaseSoapUrl implements SoapUrl {
#Override
public String getNameSpace() {
return "https://host.com/AndroidWFC/";
}
#Override
public String getUrl() {
return "https://host.com/AndroidWFC/MobileWS.asmx";
}
}
public class LoginSoap extends BaseSoapUrl {
#Override
public String getSoapAction() {
return "https://host.com/AndroidWFC/UserControl";
}
#Override
public String getMethodName() {
return "UserControl";
}
}
Is it possible to define following in Java:
public interface IGenericRepo<T> {
void add();
void delete();
void attach();
}
public interface IGenericRepo<Book> {
default String bookSpecificMethod(){
return "smthn";
}
}
public class NHGenericRepo<T> implements IGenericRepo<T>{
/* implementation */
}
public class NHUnitOfWork implements UnitOfWork{
#Autowired
public void setBookRepo(NHGenericRepo<Book> bookRepo) {
this.bookRepo= bookRepo;
}
public NHGenericRepo<Book> getBookRepo() {
return bookRepo;
}
private NHGenericRepo<Book> bookRepo;
}
And to be able somewhere in code to have:
{
#Autowired
public void setNhuw(NHUnitOfWork nhuw) {
this.nhuw = nhuw;
}
private NHUnitOfWork nhuw;
/**/
{
String st = this.nhuw.getBookRepo().bookSpecificMethod();
}
}
In .net this is possible by using Extension Method with "this IGenericRepo<Book>" as a first method parameter.
The closest you can come is:
public interface IBookGenericRepo extends IGenericRepo<Book> {
void BookSpecificMethod();
}
I was trying to understand Decorator Pattern. Below is the code am trying to understand how it works.
public static void main(String[] args)
{
Room myRoom = new CurtainDecorator(new ColorDecorator(new SimpleRoom()));
System.out.println(myRoom.showRoom());
}
Below is my Concrete Class
public class SimpleRoom implements Room{
#Override
public String showRoom()
{
return "show room";
}
}
Below is my abstract Decorator class
public abstract class RoomDecorator implements Room{
public Room roomReference;
#Override
public String showRoom()
{
return roomReference.showRoom();
}
}
Below is my Decorator implementation1
public class ColorDecorator extends RoomDecorator{
#Override
public String showRoom()
{
return addColors(); //How does showRoom() method gets invoked here?
}
public ColorDecorator(Room room)
{
this.roomReference = room;
}
public String addColors()
{
return "Blue";
}
}
Below is my Decorator implementation 2
public class CurtainDecorator extends RoomDecorator{
public CurtainDecorator(Room room)
{
this.roomReference = room;
}
#Override
public String showRoom()
{
return this.roomReference.showRoom() + addCurtains(); //What will showRoom method invoke?
}
public String addCurtains()
{
return "Curtain";
}
}
Output is - BlueCurtain
My question are placed in the comment..
In the end you have:
CurtainDecorator(ref=ColorDecorator(ref=SimpleRoom)))
When you call showRoom from main, it calls the method of CurtainDecorator, which in turn first goes to it's reference (ColorDecorator in this case) that outputs 'Blue', then CurtainDecorator adds it's bit 'Curtain'.