欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

跟着项目学设计模式(四):抽象工厂模式

程序员文章站 2024-01-20 19:45:28
...

接上文,上次重构之后,还是比较顺利的,项目持续交付,众人各有所得,只是开发进度以前是卡在类库这边的,现在呢,慢慢的转移到网站这边了,这种情况愈演愈烈,终于到了不得不关注的时候了。

为什么网站这边进度慢了?

网站开发人员:以前的模块基本没有什么业务逻辑,我只需要关注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)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

所以多层模式里的产品类纵向分组,构成了一个产品族,每个产品族对应一个产品接口,抽象工厂模式就是【横向工厂模式+纵向简单工厂】,牺牲一部分可维护性,达到减少系统复杂度的目的。