实现一个功能,假设如今有跑车,越野车,商务车,想要开什么车的时候随时能发车。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();
}
}复制代码
可能会由于注入的具体实现不一样而获得不一样的服务功能;