Factory_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki
- (Factory Method) ํ ์ ์ ๋ฐ๋ ์ค๋ธ์ ํธ๋ฅผ ๊ตฌํํด๋ณด์.
- (Factory Method) ์ ์ฒด์ฝ๋
- Factory ๊ตฌํ ์ ์ฒด์ฝ๋
- Inner Factory
- Abstract Factory
cartesian, polar๋ก ์ ์ ๋ฐ์ ์ ์๋ค๊ณ ์๊ฐํ๋ฉด ์์ฑ์๋ฅผ ์ด๋ป๊ฒ ๋ง๋ค์ด์ผํ ๊น?
enum class PointType
{
cartesian,
polar
};
struct Point
{
//Point(float x, float y) : x(x), y(y) {}
// param a this is either x or rho
// param b this is either y or theta
// param type
Point(float a, float b, PointType type = PointType::cartesian)
{
if(type == PointType::cartesian)
{
x = a;
y = b;
} else {
x = a * cos(b);
y = a * sin(b);
}
}
float x, y;
};
int main()
{
return 0;
}ํ ... ์ด๊ฒ ๊ณผ์ฐ ์ต์ ์ธ๊ฐ? ์์ฑ์์ ๋งค๋ฒ cartesian, polar์ธ์ง ์ ์ด์ฃผ๋๊ฒ ์ต์ ์ธ๊ฐ?
์ด๋ฐ ์ฝ๋๋ ์ด๋จ๊น? ์์ฑ์ ์์ฒด์์ cartesian, polar๋ฅผ ์ ํํ๊ฒ ํด๋ณด์.
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
enum class PointType
{
cartesian,
polar
};
class Point
{
/*Point(float a, float b, PointType type = PointType::cartesian)
{
if (type == PointType::cartesian)
{
x = a; b = y;
}
else
{
x = a*cos(b);
y = a*sin(b);
}
}*/
Point(const float x, const float y)
: x{x},
y{y}
{
}
public:
float x, y;
friend std::ostream& operator<<(std::ostream& os, const Point& obj)
{
return os
<< "x: " << obj.x
<< " y: " << obj.y;
}
static Point NewCartesian(float x, float y)
{
return{ x,y };
}
static Point NewPolar(float r, float theta)
{
return{ r*cos(theta), r*sin(theta) };
}
};
int main_z()
{
// will not work
//Point p{ 1,2 };
auto p = Point::NewPolar(5, M_PI_4);
std::cout << p << std::endl;
getchar();
return 0;
}Method๋ณด๋ค ์ด๋ฐ๋ฐฉ์์ ์ ํธํ๋ค.
#include <cmath>
enum class PointType
{
cartesian,
polar
};
class Point
{
/*Point(float a, float b, PointType type = PointType::cartesian)
{
if (type == PointType::cartesian)
{
x = a; b = y;
}
else
{
x = a*cos(b);
y = a*sin(b);
}
}*/
// use a factory method
Point(float x, float y) : x(x), y(y){}
public:
float x, y;
friend class PointFactory;
};
class PointFactory
{
static Point NewCartesian(float x, float y)
{
return Point{ x,y };
}
static Point NewPolar(float r, float theta)
{
return Point{ r*cos(theta), r*sin(theta) };
}
};
int main()
{
auto p = PointFacory::NewPolar(5, M_PI_4);
cout << p << endl;
return 0;
}#include <cmath>
// do not need this for factory
enum class PointType
{
cartesian,
polar
};
class Point
{
/*Point(float a, float b, PointType type = PointType::cartesian)
{
if (type == PointType::cartesian)
{
x = a; b = y;
}
else
{
x = a*cos(b);
y = a*sin(b);
}
}*/
// use a factory method
Point(float x, float y) : x(x), y(y) {}
class PointFactory
{
PointFactory() {}
public:
static Point NewCartesian(float x, float y)
{
return { x,y };
}
static Point NewPolar(float r, float theta)
{
return{ r*cos(theta), r*sin(theta) };
}
};
public:
float x, y;
static PointFactory Factory;
};
int main_2()
{
// will not work
// Point p{ 1,2 };
// nope!
// Point::PointFactory pf;
// if factory is public, then
//auto p = Point::PointFactory::NewCartesian(3, 4);
// at any rate, use this
auto pp = Point::Factory.NewCartesian(2, 3);
return 0;
}// AbstractFactory.cpp
#include <iostream>
#include <memory>
#include <map>
#include "HotDrink.h"
#include "DrinkFactory.h"
using namespace std;
unique_ptr<HotDrink> make_drink(string type)
{
unique_ptr<HotDrink> drink;
if (type == "tea")
{
drink = make_unique<Tea>();
drink->prepare(200);
}
else
{
drink = make_unique<Coffee>();
drink->prepare(50);
}
return drink;
}
int main53()
{
auto d = make_drink("tea");
DrinkFactory df;
df.make_drink("coffee");
getchar();
return 0;
}// DrinkFactory.h
#pragma once
#include <string>
#include "HotDrink.h"
#include "TeaFactory.h"
#include "CoffeeFactory.h"
#include <map>
#include <functional>
struct HotDrink;
class DrinkFactory
{
map<string, unique_ptr<HotDrinkFactory>> hot_factories;
public:
DrinkFactory()
{
hot_factories["coffee"] = make_unique<CoffeeFactory>();
hot_factories["tea"] = make_unique<TeaFactory>();
}
unique_ptr<HotDrink> make_drink(const string& name)
{
auto drink = hot_factories[name]->make();
drink->prepare(200); // oops!
return drink;
}
};
class DrinkWithVolumeFactory
{
map<string, function<unique_ptr<HotDrink>()>> factories;
public:
DrinkWithVolumeFactory()
{
factories["tea"] = [] {
auto tea = make_unique<Tea>();
tea->prepare(200);
return tea;
};
}
unique_ptr<HotDrink> make_drink(const string& name);
};
inline unique_ptr<HotDrink> DrinkWithVolumeFactory::make_drink(const string& name)
{
return factories[name]();
}// HotDrinkFactory.h
#pragma once
#include "HotDrink.h"
struct HotDrinkFactory
{
virtual unique_ptr<HotDrink> make() const = 0;
};// CoffeeFactory.h
#pragma once
#include <memory>
#include "HotDrink.h"
#include "HotDrinkFactory.h"
struct HotDrink;
struct CoffeeFactory : HotDrinkFactory
{
unique_ptr<HotDrink> make() const override
{
return make_unique<Coffee>();
}
};// HotDrink.h
#pragma once
#include <memory>
#include <map>
#include <string>
using namespace std;
struct HotDrink
{
virtual ~HotDrink() = default;
virtual void prepare(int volume) = 0;
};
struct Tea : HotDrink
{
void prepare(int volume) override
{
cout << "Take tea bag, boil water, pour " << volume << "ml, add some lemon" << endl;
}
};
struct Coffee : HotDrink
{
void prepare(int volume) override
{
cout << "Grind some beans, boil water, pour " << volume << "ml, add cream, enjoy!" << endl;
}
};