【大话设计模式】——工厂模式家族

2021-01-29 13:36:17 浏览数 (1)

在工厂模式家族中最出名的是工厂三姐妹,根据抽象的程度不同分为简单工厂、工厂模式和抽象工厂模式。他们在我们平时的编程中会经常使用。所以我们应该详细地了解一下他们三者之间优缺点。

简单工厂

定义

简单工厂模式又叫做静态工厂方法(Static FactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

举例说明:

代码实现:

代码语言:javascript复制
<span style="font-size:18px;">//客户端代码
        static void Main(string[] args)
        {
            Operation oper;
            oper = OperationFactory.createOperate("*");
            oper.NumberA = 1;
            oper.NumberB = 2;
            double result = oper.GetResult();

            
        }
    }
     //Operation运算类
    public class Operation
    {
        private double _numberA = 0;
        private double _numberB = 0;

        public double NumberA
        {
            get { return _numberA; }
            set { _numberA = value; }

        }
        public double NumberB
        {
            get { return _numberB; }
            set { _numberB = value; }
        }
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
    }

    //加减乘除类
    class OperationAdd : Operation  //加法类,继承运算类
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA   NumberB;
            return result;
        }
    }
    class OperationSub : Operation //减法类,继承运算类
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA - NumberB;
            return result;
        }
    }

    class OperationMul : Operation //乘法类,继承运算类
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA * NumberB;
            return result;

        }
    }

    class OperationDiv : Operation  //除法类,继承运算类
    {
        public override double GetResult()
        {
            double result = 0;
            if (NumberB == 0)
                throw new Exception("除数不能为0。");

            result = NumberA / NumberB;
            return result;
        }
    }
    //简单运算工厂类

    class OperationFactory
    {
        public static Operation createOperate(string operate)
        {
            Operation oper = null;
            switch (operate)
            {
                case " ":
                    oper = new OperationAdd();
                    break;
                case "-":
                    oper = new OperationSub();
                    break;
                case "*":
                    oper = new OperationMul();
                    break;
                case "/":
                    oper = new OperationDiv();
                    break;
            }
            return oper;
        }
    }</span>

简单工厂的优点:

1、工厂类是整个模式的关键.包含了必要的逻辑判断,根据给定的信息,决定究竟应该创建哪个具体类的实例。

2、明确了各自的职责和权利,有利于整个软件体系结构的优化。

简单工厂的缺点:

1、由于工厂类集中了所有实例的创建逻辑,违反了高内聚低耦合原则,将全部创建逻辑集中到了一个工厂类中;

2、它所能创建的类只能是事先考虑到的,每次扩展都需要更改工厂类,违反了开放封闭原则。

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例。

工厂模式

定义:

用于创建对象的接口,让子类决定实例化哪一个类。工厂模式对类的实例化延迟到其子类。

举例说明:数据访问程序

代码实现:

代码语言:javascript复制
<span style="font-size:18px;"> static void Main(string[] args)
        {
            User user = new User();
            IFactory factory = new SqlServerFactory();
            IUser iu = factory.CreateUser();
            iu.Insert(user);
            iu.GetUser(1);

            Console.Read();
        }
    }
    //User类
    class User
    {
        private int _id;
        public int ID
        {
            get {return _id;}
            set {_id=value;}
        }
        private string _name;
        public string Name
        {
            get {return _name;}
            set {_name =value ;}
        }
    }
    //IUser接口
    interface IUser
    {
        void Insert(User user);
        User GetUser(int id);
    }
    //SqlserverUser类
    class SqlserverUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在SQL Server 中给User表增加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine("在SQL Server 中根据ID得到User表一条记录");
            return null;
        }
    }
    //AccessUser类
    class AccessUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Access中给User表增加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine("在Access中根据ID得到User表一条记录");
            return null;
        }
    }
    //IFactory接口
    interface IFactory
    {
        IUser CreateUser();
    }
    //SqlServerFactory :IFactory
    class SqlServerFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new AccessUser();
        }
    }
    //AccessFactory类
    class AccessFactory:IFactory 
    {
        public IUser CreateUser()
        {
            return new AccessUser();
        }
    }</span>

工厂模式的优点:

1、克服了简单工厂违背开放封闭原则的缺点,保持了封装的优点。工厂模式集中封装了对象的创建,更换对象时更加容易。 2、使用了多态性,保持了简单工厂的优点。 3、降低耦合度。降低了客户程序与产品对象的耦合。

抽象工厂

定义:

创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

举例说明:数据访问程序

代码实现:

代码语言:javascript复制
<span style="font-size:18px;"> static void Main(string[] args)
        {
            User user=new User ();
            Department dept = new Department();
            //IFactory factory = new SqlServerFactory();
            IFactory factory = new AccessFactory();

            IUser iu = factory.CreateUser();

            iu.Insert(user);
            iu.GetUser(1);

            IDepartment id = factory.CreateDepartment();
            id.Insert(dept);
            id.GetDepartment(1);

            Console.Read();
            
        }
    }
    class User   //用户类
    {
        private int _id;
        public int ID
        {
            get {return _id;}
            set {_id =value;}
        }
        private string _name;
        public string Name
        {
            get {return _name ;}
            set {_name =value ;}
        }
    }
    //IUser接口
    interface IUser 
    {
        void Insert(User user);
        User GetUser(int id);
    }
    // IUser接口的子SqlserverUser类,用于访问SQL Server的User
    class SqlserverUser :IUser 
    {
        public void Insert(User user)
        {
            Console.WriteLine("在SQL Server中给User表增加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine ("在SQL Server中根据ID得到User表一条记录");
            return null;
        }
    }
    // IUser接口的子AccessUser类,用于访问Access的User

    class AccessUser :IUser 
    {
        public void Insert(User user)
        {
            Console.WriteLine ("在Access中给User表增加一条记录");
        }
        public User GetUser(int id)
        {
            Console.WriteLine ("在Access中根据ID得到User表中一条记录");
            return null;
        }
    }
    //增加一个Department表
    class Department
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            set { ID = value; }
        }
        private string _deptName;
        public string DeptName
        {
            get { return _deptName; }
            set { DeptName = value; }
        }
    }

    //IDpartment接口
        interface IDepartment
    {
        void Insert(Department department);

        Department GetDepartment(int id);
    }
    //sqlserverDepartment类
        class SqlserverDepartment : IDepartment
        {
            public void Insert(Department department)
            {
                Console.WriteLine("在SQL Server中给Department表增加一条记录");
            }
            public Department GetDepartment(int id)
            {
                Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
                return null;
            }
        }
    //AccessDepartment类
        class AccessDepartment : IDepartment
        {
            public void Insert(Department department)
            {
                Console.WriteLine("在Access中给Departmen表增加一条记录");
            }
            public Department GetDepartment(int id)
            {
                Console.WriteLine("在Access中根据ID得到Departmen表一条记录");
                return null;
            }
        }
    //抽象工厂的接口
    interface IFactory
    {
        IUser CreateUser();
        IDepartment CreateDepartment(); //增加的接口方法
    }
    class SqlServerFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new SqlserverUser();
        }
        public IDepartment CreateDepartment()
        {
            return new AccessDepartment();
        }
    }
    class AccessFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new AccessUser();
        }
        public IDepartment CreateDepartment()
        {
            return new AccessDepartment();
        }
    }</span>

抽象工厂的优点:

抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部创建不同的产品对象。

抽象工厂的缺点:

对于增加需求,扩展程序时,需要增加许多子类,使得程序变得臃肿,麻烦。(此时可以利用放射 抽象工厂的方法避免)。

总结:

无论是简单工厂模式,工厂模式,还是抽象工厂模式,他们都属于工厂模式,并且是创建型模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。

0 人点赞