代码改变世界

工厂模式

2019-03-13 17:03  .net小跟班(杜)  阅读(282)  评论(0编辑  收藏  举报

1、定义:

工厂模式是用工厂方法代替new操作的一种模式。工厂方法封装了多个相关联类的new方法,每次实例化这些类的时候不需要new多次,只需要调用工厂类的对应方法即可实例化这些类,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式分为三种:简单工厂、工厂方法、抽象工厂。

简单工厂模式由三种角色组成:
1、工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,根据逻辑不通,产生具体的工厂产品。如例子中的Driver类。
2、抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。如例中的Car接口。
3、具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现,如例子中的Benz、Bmw类。

工厂方法模式先来看下它的组成吧:
1.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
3.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象。
而且使用抽象工厂模式还要满足一下条件:
1.系统中有多个产品族,而系统一次只可能消费其中一族产品
2.同属于同一个产品族的产品以其使用。
来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):
a.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
b.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
c.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
  具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

对比:

工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

参考优点:在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。

基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类。

使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

参考缺点:在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

适用的场景:客户端不知道它所需要的对象的类。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。

抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。

简单工厂模式:

1、首先创建两个类:学生类和老师类  实现分别调用  使用三层架构体现

2、DAL层封装IdataServer增删改查接口类

int Create(T t);
        int Delete(T t);
        int Update(T t);
        DataTable GetData();
        DataTable GetDataById(int id);

3、DAL层封装factory工厂模式类

public class Factory<T>
    {
        public static IDataServer<T>CreateDal(string classname)
        {
            IDataServer<T> server = null;
            switch (classname)
            {
                case "stu":
                    server = new StudentDal() as IDataServer<T>;
                    break;
                case "tea":
                    server = new TeacherDal() as IDataServer<T>;
                    break;
            }
            return server;
        }
    }

4、BLL层StudentBll调用工厂类

public class StudentBll
    {
        IDataServer<StudentInfo> addserver = Factory<StudentInfo>.CreateDal("stu");
        public int Create(StudentInfo t)
        {
            return addserver.Create(t);
        }
    }

控制器写法不变

抽象工厂模式

假如中国对邪恶国家开战。

中国装备:炸弹类,坦克类,来消灭邪恶国家。

炸弹类:导弹,核弹;

坦克类:步战车,主站坦克;

战略:

前期中国兵工厂生产:导弹,越野车,打击邪恶国家。

后期中国兵工厂生产:核弹,主站坦克,毁灭邪恶国家。

#region 炸弹系列
        public abstract class Bomb
        {
            abstract public void baozha();
        }
        //导弹
        public class daodanBomb : Bomb
        {
            public override void baozha()
            {
                Console.WriteLine("我是一颗中国造导弹,随时待命!");
            }
        }
        //核弹
        public class hedanBomb : Bomb
        {
            public override void baozha()
            {
                Console.WriteLine("我是一颗中国造核弹,彻底摧毁!");
            }
        }
        #endregion
        #region 坦克
        public abstract class Tank
        {
            abstract public void go();
        }
        //步战车
        public class buzhanche : Tank
        {
            public override void go()
            {
                Console.WriteLine("我们是中国装甲部队,随时待命!");
            }
        }
        public class zhuzhanTank : Tank
        {
            public override void go()
            {
                Console.WriteLine("我们是中国坦克部队,碾压所有!");
            }
        }
        #endregion
        #region 中国兵工厂
        public abstract class chinaFactory
        {
            //坦克制造车间
            public abstract Tank CreateTank();
            //炸弹制造车间
            public abstract Bomb CreateBomb();
        }
        //兵工厂前期制造
        public class qianqiFactory : chinaFactory
        {
            public override Bomb CreateBomb()
            {
                //导弹
                return new daodanBomb();
            }

            public override Tank CreateTank()
            {
                //步战车
                return new buzhanche();
            }
        }
        public class houqiFactory : chinaFactory
        {
            public override Bomb CreateBomb()
            {
                //核弹
                return new hedanBomb();
            }

            public override Tank CreateTank()
            {
                //主战坦克
                return new zhuzhanTank();
            }
        }
        #endregion
        #region 打仗
        //备战
        public class Make
        {
            //装备
            private Bomb bomb;
            private Tank tank;
            //制造加工
            public Make(chinaFactory factory)
            {
                bomb = factory.CreateBomb();
                tank = factory.CreateTank();
            }
            //开战
            public void warStar()
            {
                //炸弹爆炸
                bomb.baozha();
                //战车前进
                tank.go();
            }
        }
        #endregion
        public static void Main(string[] args)
        {
            //打仗前期
            chinaFactory qianqiMake = new qianqiFactory();
            Make qianqi = new Make(qianqiMake);
            qianqi.warStar();

            //点击任意键,进行后期作战
            Console.ReadKey();
            chinaFactory houqiMake = new houqiFactory();
            Make houqi = new Make(houqiMake);
            houqi.warStar();

            Console.WriteLine("中国军队,所向披靡");
            Console.ReadKey();
        }