-1

I am trying ot understand how to apply a the simple factory pattern to an assigment I have but I do not understand how to do it.

This is the request: Apply the Simple Factory pattern that creates the appropriate Strategy object. Remember, this is a Simple Factory pattern. Draw the UML diagram of the new design.

We already implemented the strategy pattern but I do not understand how to apply the simple factory pattern to the code. I understand that the simple factory pattern is supposed to provide encapsulation for the creation of the object but I do not see how the examples I have found show how to apply to this. Any help would be appreciated.

EDIT: Updated code EDIT: Changed code to make use of polymorphism

package Client;

import domain.Loan;
import factory.StrategyFactory;
import strategy.ComplexLoan;
import strategy.ICapitalStrategy;

public class Client {
    public static void main(String[] args){
        Loan complexLoan = new Loan(2.2, 2, 3.3, 4.4, 5, 6, 7, StrategyFactory.getComplexStrategy());
        System.out.print("hello");

    }

}

package factory;

import strategy.ComplexLoan;
import strategy.ICapitalStrategy;
import strategy.RevolvingLoan;
import strategy.TermLoan;



public class StrategyFactory {
    /*
    public static ICapitalStrategy getStrategy(String type) {       
        if (type.equals("Complex")){
            return new ComplexLoan();
        }
        else if (type.equals("Revolving")){
            return new RevolvingLoan();
        }
        else if (type.equals("Term")){
            return new TermLoan();
        }
        return null;
    }
    */

    public static ICapitalStrategy getComplexStrategy() {
        return new ComplexLoan();
    }
    public static ICapitalStrategy getRevolvingStrategy() {
        return new RevolvingLoan();
    }
    public static ICapitalStrategy getTermStrategy() {
        return new TermLoan();
    }
}

    package domain;
    import strategy.ICapitalStrategy;


    public class Loan {
        private ICapitalStrategy strategy;

        double commitment;
        int duration;
        double riskFactor;
        double unusedPercentage;
        int outstandingRiskAmount;
        int unusedRiskAmount;
        double unusedRiskFactor;
        double capital;

        public Loan(double commit, int dura, double rskFact, double unusedPer,
                    int outStandRskAmt, int unusedRskAmt, double unusedRskFac,
                    ICapitalStrategy strat) {
            this.commitment = commit;
            this.duration = dura;
            this.riskFactor = rskFact;
            this.outstandingRiskAmount = outStandRskAmt;
            this.unusedRiskAmount = unusedRskAmt;
            this.unusedRiskFactor = unusedRskFac;
            this.strategy = strat;

        }

        public double CalculateCapital() {
            return strategy.CapitalLoan(this);
        }

        public double getCommitment() {
            return commitment;
        }

        public void setCommitment(double c) {
            commitment = c;
        }

        public int getDuration() {
            return duration;
        }

        public void setDuration(int dur) {
            duration = dur;
        }

        public double getRiskFactor() {
            return riskFactor;
        }

        public void setRiskFactor(double rskFac) {
            riskFactor = rskFac;
        }

        public double getUnusedPercentage() {
            return unusedPercentage;
        }

        public void setUnusedPercentage(double unusedPercent) {
            unusedPercentage = unusedPercent;
        }

        public double getOutstandingRiskAmount() {
            return outstandingRiskAmount;
        }

        public void setOutstandingRiskAmount(int outStandingRskAmt) {
            outstandingRiskAmount = outStandingRskAmt;
        }

        public double getUnusedRiskAmount() {
            return unusedRiskAmount;
        }

        public void setUnusedRiskAmount(int UnusedRskAmt) {
            unusedRiskAmount = UnusedRskAmt;
        }

        public double getUnusedRiskFactor() {
            return unusedRiskFactor;
        }

        public void setUnusedRiskFactor(double unusedRskFac) {
            unusedRiskFactor = unusedRskFac;
        }

        public Loan(ICapitalStrategy strategy) {
            this.strategy = strategy;
        }

        /*public double executeStrategy() {
            return this.strategy.CapitalLoan(this);
        }
        */
    }

    package strategy;

    import domain.Loan;

    public class ComplexLoan implements ICapitalStrategy {

        @Override
        public double CapitalLoan(Loan l) {
            return ((l.getOutstandingRiskAmount() * l.getDuration() * l.getRiskFactor()) + (l.getUnusedRiskAmount() 
                    * l.getDuration() * l.getUnusedRiskFactor() ));
        }

    }

    package strategy;

    import domain.Loan;

    public interface ICapitalStrategy {
        public double CapitalLoan(Loan l);
    }

    package strategy;

    import domain.Loan;

    public class RevolvingLoan implements ICapitalStrategy {

        @Override
        public double CapitalLoan(Loan l) {
            return (l.getCommitment() * l.getUnusedPercentage() * l.getDuration() *l.getRiskFactor());  
        }

    }

    package strategy;

    import domain.Loan;

    public class TermLoan implements ICapitalStrategy {
        public TermLoan() {

        }
        public double CapitalLoan(Loan l) {
            return (l.getCommitment() * l.getDuration() * l.getRiskFactor());
        }

    }
user3577756
  • 643
  • 1
  • 9
  • 13
  • *"I do not see how the examples I have found show how to apply to this."* We would be guessing too. It should be in your assignment specification. If it's not, you should ask the instructor. – Radiodef Nov 19 '14 at 01:24
  • @Radiodef It was more of a heads up that I ahve looked at resources online but it still isn't clear so I could get a more guided explanation. – user3577756 Nov 19 '14 at 03:23

3 Answers3

3

Here's a likely helpful bit about Simple Factory Pattern[1]:

The simple factory isn't actually a pattern; it's more of a design principle. The simple factory encapsulates the object creation code, but keeps control over how the object is created. Simple factories are often designed as a class with a static method (aka static factory) that returns the object requested.

Here's an example, not suited directly to your example in order to make you think a bit hard for your homework :)

interface Foo{
  double calculateStuff();
}

class MyClass implements Foo{
  @Override
  public double calculateStuff(){
    //logic goes here
  }
}

class MyFactory {
  public static double getCalculatedStuff(){
    return new MyClass().calculateStuff();
  }
}

class RunCode {
  public static void main(String[] args){
     double stuff = MyFactory.getCalculatedStuff();
  }
}

EDIT:

class LoanFactory{

    public static double getComplexLoan(Loan l){
        return new ComplexLoan().CapitalLoan(l);
    }
}

another way (which has its uses, but in this case I prefer the method above):

class ComplexLoan implements ICapitalStrategy{
    private ComplexLoan(){
    }

    public static double getLoan(Loan l){
        return new ComplexLoan().CapitalLoan(l);
    }
}

or this option that explicitly displays polymorphism:

class LoanFactory{

    public static ICapitalStrategy getComplexLoan(){
        return new ComplexLoan();
    }
}

One other thing that is important to note: convention says method names should start with a lowercase letter, so your CapitalLoan() would be capitalLoan().

Also, there's no need to prefix your interfaces with an I, so your ICapitalStrategy would become CapitalStrategy.

victorantunes
  • 1,141
  • 9
  • 20
  • 1
    The OP said they have already looked at examples. Also, your example is not entirely correct. Factory Pattern is generally an object one uses to create other objects, not a static utility class for performing a computation. – Radiodef Nov 19 '14 at 01:31
  • Yes, my example regarding computations isn't the best choice for exemplifying factory pattern, but I believe it is simple enough for OP to understand. Also, OP said they didn't understand the examples they found. – victorantunes Nov 19 '14 at 01:43
  • @victorantunes So I would basically need to create a factor for each subclass of my interface? – user3577756 Nov 19 '14 at 03:29
  • Not really. The point is to have only one Factory class, and have one method for each class that implements your `Strategy` interface, and have that method return an instance of said class. Are you getting somewhere now? I'm trying to point you in the right direction without giving you the exact answer to your homework. You're supposed to think :p – victorantunes Nov 19 '14 at 03:33
  • @victorantunes Well all of the examples I have found online seem a easier than this. I think I may be making progress. Just kind of fried at the moment. – user3577756 Nov 19 '14 at 03:48
  • @victorantunes I get that a factory could have a chain of If/else statements that determins which on is created but in the case of my code it is done already by what is passed when the loan is created. I do not understand how I am supposed to etract that into a class. – user3577756 Nov 19 '14 at 04:05
  • @victorantunes I think I figured it out right as you posted your new edits. Let me know if it looks correct. – user3577756 Nov 19 '14 at 04:21
  • Yes, it is one correct way of doing it, but since you have polymorphism going on (classes which implement `ICapitalStrategy`), you could ditch the `String type` argument in this case, and go for several methods, one directed at each class that implements `ICapitalStrategy`. I've updated my answer to illustrate this. – victorantunes Nov 19 '14 at 04:27
  • @victorantunes Yeah i think it just all clicked. I changed it to actually use the polymorphism and I think I understand it now. Let me know if you see anything else. – user3577756 Nov 19 '14 at 04:35
1

In the following example. The "Document" is abstract class and "html" document. "MyDocument" and "pdf" are concrete class. As long as you provide parameter with valid string, you will get the corresponding concrete class. For example if you put "pdf" as a parameter, you will get pdf document. Document type is all you need to accept whatever type of documents you want to create.

public Document CreateDocument(String type){
if (type.isEqual("html"))
    return new HtmlDocument();
if (type.isEqual("proprietary"))
    return new MyDocument();
if (type.isEqual("pdf"))
    return new PdfDocument ();
}

There is a better documented article thread in Examples of GoF Design Patterns in Java's core libraries

Community
  • 1
  • 1
zawhtut
  • 8,335
  • 5
  • 52
  • 76
  • I think I figured it out let me know if it looks correct. – user3577756 Nov 19 '14 at 04:22
  • You can use generics too. Writing three different methods for three type of concrete class can effect the scalibility in my opinion. http://stackoverflow.com/questions/6191710/am-i-implementing-a-generics-based-java-factory-correctly – zawhtut Nov 19 '14 at 05:24
1
public interface PaymentMethod {
    public void makePayment();
}

class CreditCard implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through credit card...");
    }
}

class NetBanking implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through net banking...");
    }
}

public class PaymentMethodFactory {
    public static PaymentMethod getPaymentMethod(String method) {
        if ("creditcard".equalsIgnoreCase(method)) {
            return new CreditCard();
        } else if ("netbanking".equalsIgnoreCase(method)) {
            return new NetBanking();
        } else {
            throw new IllegalArgumentException("Payment method not supported!");
        }
    }
}

public class SimpleFactoryTest {

    public static void main(String[] args) {
        PaymentMethodFactory factory = new PaymentMethodFactory();
        PaymentMethod paymentMethod = factory.getPaymentMethod("creditcard");
        paymentMethod.makePayment();
    }

}
Vivek Goel
  • 762
  • 2
  • 10
  • 21