場景:解除上端對細節的依賴,把細節包一層,在另一層中處理
抽象類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesignMode.Interface
{
public abstract class BasePhone
{
public abstract void Call();
public abstract void Text();
}
}
蘋果手機
using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleFactory
{
public class iPhone : BasePhone
{
public override void Call()
{
Console.WriteLine("use {0} call", this.GetType().Name);
}
public override void Text()
{
Console.WriteLine("use {0} text", this.GetType().Name);
}
}
}
華爲手機
using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleFactory
{
public class Honor : BasePhone
{
public override void Call()
{
Console.WriteLine("use {0} call", this.GetType().Name);
}
public override void Text()
{
Console.WriteLine("use {0} text", this.GetType().Name);
}
}
}
三星手機
using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleFactory
{
public class Galaxy : BasePhone
{
public override void Call()
{
Console.WriteLine("use {0} call", this.GetType().Name);
}
public override void Text()
{
Console.WriteLine("use {0} text", this.GetType().Name);
}
}
}
工廠類
using Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
/// <summary>
/// 解除上端對細節的依賴,把細節放到工廠中去
/// </summary>
public class ObjectFactory
{
/// <summary>
/// 創建對象
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static BasePhone CreateBasePhone(PhoneType type)
{
switch (type)
{
case PhoneType.Galaxy:
return new Galaxy();
case PhoneType.iPhone:
return new iPhone();
case PhoneType.Honor:
return new Honor();
default:
throw new Exception("wrong PhoneType");
}
}
/// <summary>
/// 枚舉
/// </summary>
public enum PhoneType
{
Galaxy,
iPhone,
Honor
}
}
}
上端調用
using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BasePhone galaxy = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.Galaxy);
BasePhone iphone = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.iPhone);
Console.ReadKey();
}
}
}
到這 實現簡單工廠基礎版
上面的上端調用 可能看起來還是有點不爽,因爲貌似還有點細節
BasePhone galaxy = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.Galaxy);
ObjectFactory.PhoneType.Galaxy
我就是不想讓上端寫明傳什麼枚舉類型
接着改造 我的工廠類 這回我用了配置文件
using Interface;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
/// <summary>
/// 解除上端對象細節的依賴,把細節放到工廠中去
/// </summary>
public class ObjectFactory2
{
/// <summary>
/// 枚舉
/// </summary>
public enum PhoneType
{
Galaxy,
iPhone,
Honor
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static BasePhone CreateBasePhoneConfig()
{
//把字符串轉換成枚舉類型
PhoneType type = (PhoneType)Enum.Parse(typeof(PhoneType), ConfigurationManager.AppSettings["PhoneType"]);
switch (type)
{
case PhoneType.Galaxy:
return new Galaxy();
case PhoneType.iPhone:
return new iPhone();
default:
throw new Exception("wrong PhoneType");
}
}
}
}
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<!--<add key="PhoneType" value="iPhone"/>-->
<add key="PhoneType" value="Galaxy"/>
</appSettings>
</configuration>
上端調用
using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BasePhone galaxy = ObjectFactory2.CreateBasePhoneConfig();
Console.ReadKey();
}
}
}
既然可以讀取配置文件來搞,那麼幹脆用反射玩
改造下簡單工廠類
using Interface;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
/// <summary>
/// 解除上端對象細節的依賴,把細節放到工廠中去
/// </summary>
public class ObjectFactory3
{
public static BasePhone CreateBasePhoneConfigReflection()
{
//通過配置文件獲取程 序集名稱 [命名空間]
string dllName = ConfigurationManager.AppSettings["dllName"];
//通過配置文件獲取類 型全名稱 [命名空間+類名]
string className = ConfigurationManager.AppSettings["className"];
//反射創建對象
return (BasePhone)Activator.CreateInstance(dllName,className).Unwrap();
}
}
}
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<!--程序集名稱 [命名空間]-->
<add key="dllName" value="Model"/>
<!--類型全名稱 [命名空間+類名]-->
<add key="className" value="Model.Galaxy"/>
</appSettings>
</configuration>
上端調用
using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BasePhone galaxy = ObjectFactory3.CreateBasePhoneConfigReflection();
Console.ReadKey();
}
}
}
最後交代一下,用反射的方式玩工廠是最靈活的,從代碼上來說 枚舉都可以去掉了 !
比方說要加個“小米”手機,那麼我們搞個“小米”類,繼承一下”手機父類”, 編譯一下,就可以跑起來,當然配置文件要改動
從程序設計原則上講,簡單工廠是違背了 “單一職責”
程序設計沒有銀彈