一、我们在不考虑设计模式时,一般写程序是这样的
// 实体类:
public class RockRoad
{
public string RoadType()
{
return "this is a RockRoad";
}
}
//应用表现部分
class Program
{
static void Main(string[] args)
{
RockRoad rRoad = new RockRoad();
Console.WriteLine(rRoad.RoadType());
}
}
注:在无需求变化(RockRoad不会变化)时,这种程序设计就可以满足要求。现在需求变化(把RockRoad改为WaterRoad)时,那么把RockRoad实体类改为WaterRoad实体类或者增加一个WaterRoad类,并且把应用表现部分的所有RockRoad对象改成WaterRoad对象,如果引用RockRoad对象非常多的时候,这种改变显然会带来很大的维护成本。因此就要求改变这种设计,引用设计模式的概念。
二、根据变化更改设计,引入抽象类
//抽象类(接口)
public abstract class Road
{
public abstract string RoadType();
}
// 实体类:继承抽象类,覆写抽象方法(具体实现)
public class RockRoad:Road
{
public override string RoadType()
{
return "this is a RockRoad";
}
}
public class WaterRoad:Road
{
public override string RoadType()
{
return "this is a WaterRoad!";
}
}
//客户程序(我们的目的就是要使这个部分变成稳定,使其不会根据实体类和应用表现部门的变化而变化,他是“根”)
public class GetRoad
{
public string NewRoad(Road road)
{
return road.RoadType();
}
}
//应用表现部分(依赖于客户程序这个“根”)
class Program
{
static void Main(string[] args)
{
WaterRoad wRoad = new WaterRoad();//在这里,可以根据客户需求,实例化具体调用的类,如也可以换成RockRoad rRoad = new RockRoad();
GetRoad getRoad = new GetRoad();
Console.WriteLine( getRoad.NewRoad(wRoad));
}
}
注:这样似乎满足了要求,但是在客户程序GetRoad类的NewRoad方法中如果不仅仅使用一个Road对象,而是根据需要可能需要N个Road对象,这样变化又要求程序进行变化,由此我们引入工厂模式(Factory Method)和原形模式(ProtoType),先来说说工厂模式
三、需求要求引入工厂模式,所谓工厂就是制造产品的地方,上面的问题就在于没办法得到多个产品(Road)。来看看工厂模式是如何生产多个产品(Road)的
//抽象类(接口) public abstract class Road
{
public abstract string RoadType();
}
// 实体类:继承抽象类,覆写抽象方法(具体实现)
public class RockRoad:Road
{
public override string RoadType()
{
return "this is a RockRoad";
}
}
public class WaterRoad:Road
{
public override string RoadType()
{
return "this is a WaterRoad!";
}
}
//我们先来构建一个生产RockRoad的工厂
public class RockRoadFactory
{
public Road CreateRockRoad()
{
return new RockRoad();
}
}
//客户程序(我们的目的就是要使这个部分变成稳定,使其不会根据实体类和应用表现部门的变化而变化,他是“根”)
public class GetRoad
{
public string NewRoad(RockRoadFactory RockRoadfactory)
{
Road road1=RockRoadfactory.CreateRockRoad();//制造第一个RockRoad
Road road2=RockRoadfactory.CreateRockRoad();//制造第一个RockRoad
Road road3=RockRoadfactory.CreateRockRoad();//制造第一个RockRoad
.......................................................................// 可以根据需求制造N多个RockRoad
return road1.RoadType()+road2.RoadType()+road3.RoadType();
}
}
//应用表现部分(依赖于客户程序这个“根”)
class Program
{
static void Main(string[] args)
{
RockRoadFactory rFactory= new RockRoadFactory();//指定生产Road的工厂
GetRoad getRoad = new GetRoad();
Console.WriteLine( getRoad.NewRoad(rFactory));
}
}
注:这里引入工厂模型后,解决了产生多个Road的问题,但是你是否留意到这个工厂是固定的,只能生产RockRoad,假如我要得到WaterRoad呢,这样要么把RockRoadFactory工厂类改成WaterRoadFactory工厂类或者去增加一个WaterRoadFactory工厂类,然后在去更改客户程序GetRoad类。这不又回到最开始的问题了吗?想想最开始我们是怎么解决这个问题的呢?对了引入抽象类,在这里也就是引入抽象工厂。
四、引入抽象工厂
//抽象类(接口) public abstract class Road
{
public abstract string RoadType();
}
// 实体类:继承抽象类,覆写抽象方法(具体实现)
public class RockRoad:Road
{
public override string RoadType()
{
return "this is a RockRoad";
}
}
public class WaterRoad:Road
{
public override string RoadType()
{
return "this is a WaterRoad!";
}
}
//我们在这里来构建抽象工厂类
public abstract class AbstactFactory
{
public abstract Road CreateRoad();
}
//构建一个生产RockRoad的工厂,实现抽象方法CreateRoad()
public class RockRoadFactory:AbstactFactory
{
public override Road CreateRoad()
{
return new RockRoad();
}
}
//构建一个生产WaterRoad的工厂,实现抽象方法CreateRoad()
public class WaterRoadFactory:AbstactFactory
{
public override Road CreateRoad()
{
return new WaterRoad();
}
}
//客户程序(我们的目的就是要使这个部分变成稳定,使其不会根据实体类和应用表现部门的变化而变化,他是“根”)
public class GetRoad
{
public string NewRoad(AbstactFactory factory)
{
Road road1=factory.CreateRoad();//制造第一个Road
Road road2=factory.CreateRoad();//制造第一个Road
Road road3=factory.CreateRoad();//制造第一个Road
.......................................................................// 可以根据需求制造N多个Road
return road1.RoadType()+road2.RoadType()+road3.RoadType();
}
}
//应用表现部分(依赖于客户程序这个“根”)
class Program
{
static void Main(string[] args)
{
RockRoadFactory rFactory= new RockRoadFactory();//指定生产Road的工厂
GetRoad getRoad = new GetRoad();
Console.WriteLine( getRoad.NewRoad(rFactory));
}
}
注:这样基本问题都得到了解决,但需求要求再变化一种Road(如OilRoad)的时候,只需要新增一个OilRoad类去继续于Road,再新增一个OilRoadFactory工厂类继承于AbstactFactory,然后在应用表现部分去实例化OilRoadFactory就可以了,其他任何地方都不需改动,实现了变修改为扩展的原则