跟着项目学设计模式(四):抽象工厂模式
接上文,上次重构之后,还是比较顺利的,项目持续交付,众人各有所得,只是开发进度以前是卡在类库这边的,现在呢,慢慢的转移到网站这边了,这种情况愈演愈烈,终于到了不得不关注的时候了。
为什么网站这边进度慢了?
网站开发人员:以前的模块基本没有什么业务逻辑,我只需要关注View就可以了,Controller里的Action也就调一下类库,现在的模块好多都要复杂的业务逻辑,需要在Action中写大量的代码,关注点变多了。
原来是单层架构局限性,还是分工不明确导致的问题呀。那就请类库开发人员受累,在添加一个类库,用作业务逻辑层吧。
public interface IUserBll
{
bool Add(BaseEntity entity);
bool Del(string id);
bool Edit(string id);
bool Select(string id);
IList<BaseEntity> GetEntitys();
}
public interface IGoodsBll
{
bool Add(BaseEntity entity);
bool Del(string id);
bool Edit(string id);
bool Select(string id);
IList<BaseEntity> GetEntitys(int pageIndex, int pageSize, out int totalCount);
}
public interface IHistoryBll
{
bool Add(BaseEntity entity);
IList<BaseEntity> GetEntitys(int pageIndex, int pageSize, out int totalCount);
}
根据工厂模式,我们依样画葫芦,就可以实现业务逻辑层了,网站开发人员很开心,现在又可以愉快的玩耍了,类库开发人员也可以接受吧,毕竟这本来就应该属于是他的分工。
但是这个计划开始之前,又有了新的变化。客户希望网站在移动端能有更友好一些,网站开发人员建议用Vue.js开发一个专门的手机版出来。那现在一个类库,有了两个消费者。对于类库开发人员来说,就需要把类库变成服务了,即前后端完全分离,消费者把以前对类库的物理引用变成网络引用,类库开发人员需要暴露一个Client层,来应对服务到底是HttpClient还是RPC。
那根据工厂模式,我们依样画葫芦,在工程里添加一个模块,要在每一个层添加一个产品接口,比如用户模块,DAL层要一个IUserDal,BLL层要一个IUserBLL,Client层要一个IUserClient。
类库开发人员说这样做的话,未免太繁琐了,我们一开始定义的工厂是按模块来分的,用户模块,就对应一个用户工厂,跟你系统分几层没有直接关系,所以不管你有多少层,我用户模块就只需要一个用户接口,就是IUser,里面定义了用户模块需要的所有方法,每个层都只要去实现IUser就可以了。针对每个模块来说,还是每个层需要实现的就实现,不需要实现的就留空。虽然还是稍微违反了开闭原则,但是站在每个模块的层面来说,每次修改接口,只需要修改对应的模块,改动量可以接受,同时大大简化了系统的复杂度,这就是抽象工厂了。
百度百科:
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
所以多层模式里的产品类纵向分组,构成了一个产品族,每个产品族对应一个产品接口,抽象工厂模式就是【横向工厂模式+纵向简单工厂】,牺牲一部分可维护性,达到减少系统复杂度的目的。
上一篇: java与设计模式(四)-工厂方法模式
下一篇: The observer Pattern