實現一個功能,假設如今有跑車,越野車,商務車,想要開什麼車的時候隨時能發車。this
抽象汽車spa
/// <summary>
/// 抽象汽車
/// </summary>
public interface ICar
{
void Run();
}複製代碼
汽車類型枚舉code
public enum CarType
{
SportCarType = 0,
JeepCarType = 1,
BusinessCarType = 2
}複製代碼
各類類型汽車實現對象
/// <summary>
/// 跑車
/// </summary>
public class SportCar : ICar
{
public void Run() {
Console.WriteLine("跑車發車");
}
}
/// <summary>
/// 越野車
/// </summary>
public class JeepCar : ICar
{
public void Run() {
Console.WriteLine("越野車發車");
}
}
/// <summary>
/// 商務車
/// </summary>
public class BusinessCar : ICar
{
public void Run() {
Console.WriteLine("商務車發車");
}
}複製代碼
工廠類繼承
public class Factory
{
public ICar GetCar(CarType carType) {
switch (carType)
{
case CarType.SportCarType:
return new SportCar();
case CarType.JeepCarType:
return new JeepCar();
case CarType.BusinessCarType:
return new BusinessCar();
default:
throw new Exception("翻車!");
}
}
}複製代碼
調用接口
class Program
{
static void Main(string[] args) {
ICar car;
Factory factory = new Factory();
Console.WriteLine("老司機跑車發車");
car = factory.GetCar(CarType.SportCarType);
car.Run();
}
}複製代碼
優勢:簡單工廠模式可以根據外界給定的信息,決定究竟應該建立哪一個具體類的對象。當要新增一個汽車類型的時候,只要實現指定接口就能夠,符合開發關閉原則。開發
缺點:很明顯工廠類集中了全部實例的建立邏輯,當要加車類型的時候須要修改工廠類源碼,違背開放關閉原則。get
簡單工廠的例子中,能夠把工廠類當作汽車倉庫,裏面是已經生產好的汽車,想要什麼類型的汽車,只要是已經生產好的就能夠獲得。源碼
如今咱們想要開大卡車,可是倉庫裏沒有,怎麼辦呢?string
咱們換個高級點的倉庫,一個能夠生產大卡車的倉庫,並且有不少這種倉庫,每一個倉庫生產指定類型的汽車。
抽象高級倉庫
public interface IFactory
{
ICar CreateCar();
}複製代碼
抽象汽車
/// <summary>
/// 抽象汽車
/// </summary>
public interface ICar
{
void Run();
}複製代碼
各類類型汽車實現
/// <summary>
/// 跑車
/// </summary>
public class SportCar : ICar
{
public void Run() {
Console.WriteLine("跑車發車");
}
}
/// <summary>
/// 越野車
/// </summary>
public class JeepCar : ICar
{
public void Run() {
Console.WriteLine("越野車發車");
}
}
/// <summary>
/// 商務車
/// </summary>
public class BusinessCar : ICar
{
public void Run() {
Console.WriteLine("商務車發車");
}
}
/// <summary>
/// 卡車
/// </summary>
public class Truck : ICar
{
public void Run() {
Console.WriteLine("卡車發車");
}
}複製代碼
具體高級倉庫
/// <summary>
/// 跑車倉庫
/// </summary>
public class SportFactory : IFactory
{
public ICar CreateCar() {
return new SportCar();
}
}
/// <summary>
/// 越野車倉庫
/// </summary>
public class JeepFactory : IFactory
{
public ICar CreateCar() {
return new JeepCar();
}
}
/// <summary>
/// 商務車倉庫
/// </summary>
public class BusinessCarFactory : IFactory
{
public ICar CreateCar() {
return new BusinessCarCar();
}
}
/// <summary>
/// 卡車倉庫
/// </summary>
public class TruckFactory : IFactory
{
public ICar CreateCar() {
return new Truck();
}
}複製代碼
調用
class Program
{
static void Main(string[] args) {
IFactory factory = new TruckFactory();
ICar truck = factory.CreateCar();
truck.Run();
}
}複製代碼
經過工廠方法模式,只要實現ICar接口,就能夠建立一種新的類型的汽車,而後經過實現IFactory接口,建立一個能夠生產這種新類型汽車的工廠。使用的時候,new一個新的工廠,就能夠生產新類型的車了。
汽車不只有不一樣類型了,還有不一樣品牌的,好比跑車類型,有勞斯萊斯的,有賓利的,有邁凱倫的。。。假設,如今咱們想開勞斯萊斯的跑車,咱們的倉庫怎麼給咱們車呢?或者說咱們怎麼從倉庫把咱們想要開的車拿到呢?工廠方法模式中咱們經過實現倉庫的多態,建立了不少能夠具體生產某種類型汽車的工廠。
如今經過實現汽車類型多態,具體的倉庫(工廠)能夠生產特定品牌不一樣類型的汽車,好比某個車庫(工廠)能夠生產賓利的跑車,商務車,越野車,卡車(滑稽)。
抽象汽車
/// <summary>
/// 抽象汽車
/// </summary>
public interface ICar
{
void Run();
}複製代碼
抽象汽車類型
/// <summary>
/// 抽象跑車類型
/// </summary>
public interface ISportCar:ICar
{
//具體品牌名稱
string Name{get;}
}
//越野車,商務車類型相似(並且這裏用抽象類更加合適)複製代碼
具體品牌的汽車類型
/// <summary>
/// 勞斯萊斯跑車
/// </summary>
public class RollsRoyceSportCar:ISportCar
{
//具體品牌名稱
public string Name
{
get{return "勞斯萊斯";}
}
public void Run(){
Console.WriteLine(this.Name+"跑車發車");
}
}
/// <summary>
/// 賓利跑車
/// </summary>
public class BentleySportCar:ISportCar
{
//具體品牌名稱
public string Name
{
get{return "賓利";}
}
public void Run(){
Console.WriteLine(this.Name+"跑車發車");
}
}
...
//越野車,商務車類型相似複製代碼
抽象車庫(工廠)
以前每一個生產具體類型汽車的倉庫(工廠)只要返回具體類型(實現ICar的汽車類)的汽車就能夠,可是如今返回特定品牌的具體類型的汽車
public interface IFactory
{
ISportCar CreateSportCar();
IJeepCar CreateJeepCar();
IJeepCar CreateJeepCar();
}複製代碼
具體工廠
/// <summary>
/// 賓利工廠
/// </summary>
public class BentleyFactory : IFactory
{
public ISportCar CreateSportCar() {
return new BentleySportCar();
}
public IJeepCar CreateJeepCar(){
return new BentleyJeepCar();
}
...
}
//其它工廠相似複製代碼
調用
class Program
{
static void Main(string[] args) {
//開賓利跑車
IFactory factory = new BentleyFactory();
ISportCar bentleySportCar = factory.CreateSportCar();
bentleySportCar.Run();
}
}複製代碼
當咱們要新增一個新的類型的汽車,只要加一個繼承ICar接口的新類型接口,而後在新類型下建立(實現新類型接口)具體品牌的汽車。可是要修改抽象工廠的源碼,而後每一個具體工廠的源碼也要修改。在現有類型的車下新增品牌就很容易
使用簡單工廠減小具體工廠的數量,這樣就能夠不用去修改具體工廠的源碼
public class Factory
{
public ISportCar CreateSportCar(string name) {
if(name=="Bentley")
{
return new BentleySportCar();
}
if(name=="RollsRoyce")
{
retutn new RollsRoyceSportCar();
}
...
}
public IJeepCar CreateJeepCar(string name) {
if(name=="Bentley")
{
return new BentleyJeepCar();
}
if(name=="RollsRoyce")
{
retutn new RollsRoyceJeepCar();
}
...
}
...
}複製代碼
調用
class Program
{
static void Main(string[] args) {
//開賓利跑車
Factory factory = new Factory();
ISportCar bentleySportCar = factory.CreateSportCar("Bentley");
bentleySportCar.Run();
}
}複製代碼
還有更加方便的方法就是使用反射
工廠模式是從工廠裏new一個服務對象出來給客戶使用,策略模式是客戶注入一個具體實例對象給工廠以使用工廠提供的服務
將上面的工廠改造一下
public class Factory
{
private ISportCar sportCar;
private IJeepCar jeepCar;
...
public CreateSportCar(ISportCar sportCar) {
this.sportCar=sportCar;
}
public CreateJeepCar(IJeepCar jeepCar) {
this.jeepCar=jeepCar;
}
...
public void SportCarRun(){
{
this.sportCar.Run();
}
public void JeepCarRun(){
{
this.jeepCar.Run();
}
}複製代碼
調用
class Program
{
static void Main(string[] args) {
//開賓利跑車
ISportCar bentleySportCar = new BentleySportCar();
Factory factory=new Factory();
factory.CreateSportCar(bentleySportCar);
factory.SportCarRun();
}
}複製代碼
可能會由於注入的具體實現不一樣而獲得不一樣的服務功能;