Factory, Abstract Factory and Factory Method

Simple Sample.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GossipDesignPattern.SimpleFactory
{
class Program
{
static void Main(string[] args)
{

Console.Write("input first number:");
string A = Console.ReadLine();

Console.Write("(+,-,*,/): ");
string B = Console.ReadLine();

Console.WriteLine("input second number:");

string C = Console.ReadLine();

string D = "";

if (B == "+")
D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));
if (B == "-")
D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));
if (B == "*")
D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));
if (B == "/")
D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));

Console.WriteLine("result: " + D);
}
}

class ProgramV2
{
static void Main(string[] args)
{

try
{
Console.Write("input first number:");
string strNumberA = Console.ReadLine();

Console.Write("(+,-,*,/): ");
string strOperate = Console.ReadLine();

Console.WriteLine("input second number:");
string strNumberB = Console.ReadLine();

string strResult = "";

switch (strOperate)
{
case "+":
strResult = Convert.ToString(Convert.ToDouble(strNumberA) + Convert.ToDouble(strNumberB));
break;
case "-":
strResult = Convert.ToString(Convert.ToDouble(strNumberA) - Convert.ToDouble(strNumberB));
break;
case "*":
strResult = Convert.ToString(Convert.ToDouble(strNumberA) * Convert.ToDouble(strNumberB));
break;
case "/":
if (strNumberB != "0")
strResult = Convert.ToString(Convert.ToDouble(strNumberA) / Convert.ToDouble(strNumberB));
else
strResult = "Divisor can't be 0";
break;
}
Console.WriteLine("result: " + strResult);

Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Error input:" + ex.ToString());
}
}
}

public class Operation
{
public static double GetResult(double numberA, double numberB, string operate)
{

double result = 0d;
switch (operate)
{
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
result = numberA / numberB;
break;
}

return result;
}

static void Main(string[] args)
{

try
{
Console.Write("input first number:");
string strNumberA = Console.ReadLine();

Console.Write("(+,-,*,/): ");
string strOperate = Console.ReadLine();

Console.WriteLine("input second number:");
string strNumberB = Console.ReadLine();

string strResult = "";

strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA), Convert.ToDouble(strNumberB), strOperate));

Console.WriteLine("result: " + strResult);

Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Error input:" + ex.ToString());
}
}
}

public class OperationBase
{
private double _numberA = 0;
private double _numberB = 0;

public double NumberA {
get { return _numberA; }
set { _numberA = value; }
}

public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}

public virtual double GetResult()
{

double result = 0;
return result;
}
}

class OperationAdd : OperationBase
{
public override double GetResult()
{

double result = 0;
result = NumberA + NumberB;
return result;
}
}

class OperationSub : OperationBase
{
public override double GetResult()
{

double result = 0;
result = NumberA - NumberB;
return result;
}
}

class OperationMul : OperationBase
{
public override double GetResult()
{

double result = 0;
result = NumberA * NumberB;
return result;
}
}

class OperationDiv : OperationBase
{
public override double GetResult()
{

double result = 0;
if (NumberB == 0)
throw new Exception("Divisor can't be 0");

result = NumberA / NumberB;

return result;
}
}

public class OperationFactory
{
public static OperationBase CreateOperate(string operate)
{

OperationBase oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}

return oper;
}

static void main(string[] args)
{

OperationBase oper;
oper = OperationFactory.CreateOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
}
}

public class FactoryMethod
{

interface IFactory
{
OperationBase CreateOperation();
}

class AddFactory : IFactory
{
public OperationBase CreateOperation()
{

return new OperationAdd();
}
}

class SubFactory : IFactory
{
public OperationBase CreateOperation()
{

return new OperationSub();
}
}

class MulFactory : IFactory
{
public OperationBase CreateOperation()
{

return new OperationMul();
}
}

class DivFactory : IFactory
{
public OperationBase CreateOperation()
{

return new OperationDiv();
}
}

static void main(string[] args)
{

IFactory operFactory = new AddFactory();
OperationBase oper = operFactory.CreateOperation();
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
}
}
}

LeiFeng.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GossipDesignPattern.SimpleFactory
{
// 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断, 根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
class LeiFeng
{
public void Sweep()
{

Console.WriteLine("Sweep!");
}

public void Wash()
{

Console.WriteLine("Wash!");
}

public void BuyRice()
{

Console.WriteLine("Buy Rice!");
}
}

class Undergraduate: LeiFeng
{
public void IamUndergraduate()
{

Console.WriteLine("I am undergraduate!");
}
}

class ProgramV3
{
static void main(string [] args)
{

LeiFeng xueleifeng = new Undergraduate();

xueleifeng.BuyRice();
xueleifeng.Sweep();
xueleifeng.Wash();

LeiFeng student1 = new Undergraduate();
student1.BuyRice();

LeiFeng student2 = new Undergraduate();
student1.Sweep();

LeiFeng student3 = new Undergraduate();
student1.Wash();
}
}

class Volunteer : LeiFeng
{
}

class SimpleFactory
{
public static LeiFeng CreateLeiFeng(string type)
{

LeiFeng result = null;
switch (type)
{
case "Undergraduate":
result = new Undergraduate();
break;
case "Volunteer":
result = new Volunteer();
break;
}

return result;
}

static void main(string[] args)
{

LeiFeng studentA = SimpleFactory.CreateLeiFeng("Undergraduate");

studentA.BuyRice();

LeiFeng studentB = SimpleFactory.CreateLeiFeng("Undergraduate");

studentB.Sweep();

LeiFeng studentC = SimpleFactory.CreateLeiFeng("Undergraduate");

studentC.Wash();
}
}

//工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点
class FactoryMethodForLeiFeng
{
interface ILeiFengFactory
{
LeiFeng CreateLeiFeng();
}

class UndergraduateFactory : ILeiFengFactory
{
public LeiFeng CreateLeiFeng()
{

return new Undergraduate();
}
}

class VolunteerFactory : ILeiFengFactory
{
public LeiFeng CreateLeiFeng()
{

return new Volunteer();
}
}

static void main(string[] args)
{

ILeiFengFactory factory = new UndergraduateFactory();

LeiFeng student = factory.CreateLeiFeng();

student.BuyRice();
student.Sweep();
student.Wash();
}
}
}