Solved

Factory Pattern

Posted on 2010-09-01
11
655 Views
Last Modified: 2013-11-13
Hi

I am working on an example in which I am creating a calculating system using factory pattern.

For that I have created a Calculator Class. Please check the code in the code section.

Now in the main function I have created the object of calculator class

IResult x = Calculator.getResult(2, 3, CalculationType.Sum);

I have 2 queries

1. Is this a valid factory pattern?
2. How can I get the sum from the code
"IResult x = Calculator.getResult(2, 3, CalculationType.Sum);"

Kindly advice

Regards
Karan Gupta


using System;



namespace ConsoleApplication1

{

    public enum CalculationType

    {

        Sum,

        Difference

    }

    // A Simple Interface

    public interface IResult

    {

        int ReturnResult(int arg1,int arg2);

    }



    public class Sum : IResult

    {

        public int ReturnResult(int arg1, int arg2)

        {

            return (arg1 + arg2);

        }

    }



    public class Difference : IResult

    {

        public int ReturnResult(int arg1, int arg2)

        {

            if (arg1 > arg2)

            {

                return (arg1 - arg2);

            }

            else

            {

                return (arg2 - arg1);

            }            

        }

    }



    public class Calculator

    {

        public static IResult getResult(int a, int b, CalculationType oCalculationType)

        {

            if (oCalculationType == CalculationType.Sum)

            {

                return new Sum();

            }

            else if (oCalculationType == CalculationType.Difference)

            {

                return new Difference();

            }

            else

            {

                throw new ApplicationException("Problem Occurs");

            }

        }

    }

}

Open in new window

0
Comment
Question by:KaranGupta
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 4

Accepted Solution

by:
ricovox earned 250 total points
Comment Utility
Hi Karan,

You are very close.
You need to change only a few things to get this to be a nice factory pattern.

In the factory pattern you create objects with a common interface as you have done. Then you can use "polymorphism" to call a method on the returned object and the result depends on what type of object was created.

After a few small modifications, you will be able to do something like this:

(I renamed IResult to ICalc to make things more clear)

ICalc x = Calculator.getCalc(CalculationType.Sum);
int answer = x.ReturnResult(2, 3);

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
Comment Utility
its not exactly a factory, you simply reflect calculation types as objects.to make it factory you probably need something like this:
 {

        Sum,

        Difference

    }



    public static class CalcFactory

    {

        public static IResult Create(CalculationType calculationType)

        {

            switch (calculationType)

            {

                case CalculationType.Sum:

                    return new Sum();

                    break;

                case CalculationType.Difference:

                    return new Difference();

                    break;

            }

        }

    }



    // A Simple Interface

    public interface IResult

    {

        int ReturnResult(int arg1, int arg2);

    }



    public class Sum : IResult

    {

        public int ReturnResult(int arg1, int arg2)

        {

            return (arg1 + arg2);

        }

    }



    public class Difference : IResult

    {

        public int ReturnResult(int arg1, int arg2)

        {

            if (arg1 > arg2)

            {

                return (arg1 - arg2);

            }

            else

            {

                return (arg2 - arg1);

            }

        }

    }



    public class Calculator

    {

        public static int getResult(int a, int b, CalculationType oCalculationType)

        {

            return CalcFactory.Create(oCalculationType).ReturnResult(a, b);

        }

    }

Open in new window

0
 
LVL 4

Expert Comment

by:ricovox
Comment Utility
Here is the whole code, with modifications.

using System;

namespace ConsoleApplication1 {
	public class Program {
		public static void Main() {
			//create the "ICalc" object, which will do the actual work for us
			ICalc x = Calculator.getCalc(CalculationType.Sum);
			int result = x.GetResult(2, 3);
			Console.WriteLine("Result of Sum: " + result);

			x = Calculator.getCalc(CalculationType.Difference);
			result = x.GetResult(2, 3);
			Console.WriteLine("Result of Diff: " + result);
		}
	}

	public enum CalculationType {
		Sum,
		Difference
	}
	// A Simple Interface
	public interface ICalc {
		int GetResult(int arg1, int arg2);
	}

	public class Sum : ICalc {
		public int GetResult(int arg1, int arg2) {
			return (arg1 + arg2);
		}
	}

	public class Difference : ICalc {
		public int GetResult(int arg1, int arg2) {
			if (arg1 > arg2) {
				return (arg1 - arg2);
			} else {
				return (arg2 - arg1);
			}
		}
	}

	public class Calculator {
		public static ICalc getCalc(CalculationType oCalculationType) {
			if (oCalculationType == CalculationType.Sum) {
				return new Sum();
			} else if (oCalculationType == CalculationType.Difference) {
				return new Difference();
			} else {
				throw new ApplicationException("Invalid calculation type.");
			}
		}
	}
}

Open in new window

0
 
LVL 4

Expert Comment

by:ricovox
Comment Utility
Notice that I added a Program class that simply uses the Calculator factory to output some results.

sedgwick's answer is also correct, but it was somewhat redundant with my first post. To benefit you most, you could compare sedgwick's full code with my full code. Both are correct factory patterns, but sedgwick added an additional function to directly get the result without returning an IResult object.
(Although this extra function is useful, this type of use actually misses the point a true factory pattern)

Good luck in your coding!
0
 
LVL 22

Expert Comment

by:ambience
Comment Utility
It is a factory pattern and it also qualifies as a factory method pattern http://en.wikipedia.org/wiki/Factory_method_pattern. The two are closely related, one differentiating factor that someone may argue is the parameter (CalculationType oCalculationType), which makes it more close to a factory method than pure-factory.
If you ask my verdict I would say its  a Factory-Method pattern, or a half-cooked builder pattern, as explained below.
How to make it a pure-factory method? Remove all the arguments from the method
public class SumCalculator {
public static ICalc getCalc() {
return new Sum();
}
}
var sumCalc = new SumCalculator();
var sum = sumCalc.getCals();
var subCalc = new SubtractionCalculator();
var sub = subCalc.getCals();
There are also a number of alternatives that you can make now
- Dont use factory, use factory method (as you already did)
- Use an abstract factory pattern, so a factory of a factory. EXAMPLE
public interface Expression {
public object evaluate(int a, int b);
}
public SumExpression : public Expression {
public object evaluate(int a, int b) {
 return a + b;
}
}
// Pure factory
public interface ExpressionFactory {
public IExpression createEvaluator() ;
}
// Pure Concrete factory
public class SumExpressionFactory : ExpressionFactory {
public  IExpression createEvaluator() {
 return new SumExpression();
}
}  
// Top level factory (uses factory method)
public class Calculator {
public static ICalc getCalculator(string operator) {
 if( operator == "sum" }
  return new SumExpressionFactory();
 }
}
}
Expression sum = Calculator.getCalculator("sum").createEvaluator();
int result = sum.evaluate( 10, 22 );
 
- Use Builder pattern, a variation of factory method and factory. EXAMPLE (This by the way is more close in essense to what your original intent appears to be). NOW a and b are no longer redundant.

public interface Expression {
public void setArg1(int a);
public void setArg2(int a);
public object evaluate();
}
public SumExpression : public Expression {
public void setArg1(int a);
public void setArg2(int a);
public object evaluate() {
 return m_a + m_b;
}
}
public class ExpressionBuilder {
public static Expression build(string type, int a, int b) {
 if( operator == "sum" }
  var e = new SumExpression();
  e.setArg1(a);
  e.setArg1(b);
  return e;
 }
}
}
Expression sum = ExpressionBuilder.build("sum", 10, 10);
int result = sum.evaluate();
 
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 22

Expert Comment

by:ambience
Comment Utility
BTW, the difference between builder and factory is that a builder uses composite steps to "construct" an object. The construction here does not mean the object coming into existence but rather coming into a state where it is deemed to be constructed (which depends upon the context).
Composite steps could be constructing different subparts of the object in sequence or even constructing multiple objects and aggregating them together or any other variant.
0
 

Author Comment

by:KaranGupta
Comment Utility
Hi

Sorry for the late reply.

ricovox:
 I have studied your code and not able to find any difference between your code and mine.

sedgwick:
You have created a method called Create(). I want to know that there is also not much difference in the code. I have come to know how to use the class. But why my class doesn't qualify factory pattern,

ambience:
Is Factory pattern, Abstract Factory and Pure factory patterns are different.


Regards
Karan Gupta
0
 
LVL 22

Expert Comment

by:ambience
Comment Utility
Well first off, I did in fact say that your code qualifies as a Factory pattern.
When I said pure factory, I intended to say a pattern that is not abstract factory or factory method. Probably there is no pure-factory pattern in text books, thats just a term i used to explain things.
I suggest that you take a look at the examples I have posted. I have already tried to explain there what subtle differences can there be between abstract factory etc.
 
0
 

Author Comment

by:KaranGupta
Comment Utility
Hi

As per the discussion I have created a document. Please let me know if there is any mistake in the tutorial so that I can use it further.



Regards
Karan
Factory-Pattern.docx
0
 
LVL 22

Assisted Solution

by:ambience
ambience earned 250 total points
Comment Utility
Oh well, the code sample appears to be the same that you have posted at the start. I suggest that at the minimum you do these changes.

public class Calculator
{
public static iCalc createOperation(CalculationType oCalculationType)
{
if (oCalculationType == CalculationType.Sum)
{
return new Sum();
}
else if (oCalculationType == CalculationType.Difference)
{
return new Difference();
}
else if (oCalculationType == CalculationType.Multiplication)
{
return new Multiplication();
}
else if (oCalculationType == CalculationType.Division)
{
return new Division();
}
else
{
throw new ApplicationException("Problem Occurs");
}
}
}
iCalc x = Calculator.createOperation(CalculationType.Sum);
int abc = x.ReturnResult(1, 2);
I have done two things
- removed unused parameters a and b
- renamed method so that it sounds more of a create something method.
Finally, I hope you do know that the code sample uses factory-method pattern.
 
0
 
LVL 22

Expert Comment

by:ambience
Comment Utility
?????????
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

Dependencies in Software Design In software development, the idea of dependencies (http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29) is an issue of some importance. This article seeks to explain what dependencies are and where they …
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now