(待完善)五种创建型设计模式总结

  • 创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 分类
  1. 工厂模式(Factory Pattern)
  2. 抽象工厂模式(Abstract Factory Pattern)
  3. 单例模式(Singleton Pattern)
  4. 建造者模式(Builder Pattern)
  5. 原型模式(Prototype Pattern)
  • 工厂模式(Factory Pattern)

定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。


C#: public abstract class Product    //抽象产品类
    {
        public abstract void method();    //抽象方法
    }
    public class ConcreteProduct:Product    //具体产品类
    {
        public override void method()
        {
            //业务逻辑处理
        }
    }
    public class Factory    //工厂类
    {
        //根据类名创建对象
        public Product GetProduct(String name)
        {
            if (name.Equals("ConcreteProduct", StringComparison.CurrentCultureIgnoreCase)) return new ConcreteProduct();
            return null;
        }
        //根据类型创建对象
        public static Product getProduct(Type type)
        {
            //判断type是否继承了Shape接口
            if (typeof(Product).IsAssignableFrom(type))
                return (Product)Activator.CreateInstance(type);
            return null;
        }
    }
    public class Client    //场景类
    {
        public static void Main(string[] args)
        {
            Factory factory = new Factory();
            Product p1 = factory.GetProduct("concreteproduct");
            Product p2 = Factory.getProduct(typeof(ConcreteProduct));
        }
    }

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 

            2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 

            3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

注意事项作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

  • 抽象工厂模式(Abstract Factory Pattern)

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


    public interface IProduct
    {
        public void method1();
    }
    public abstract class AbstractProduct1:IProduct
    {
        public abstract void method2();
    }
    public abstract class AbstractProduct2 : IProduct
    {
        public abstract void method2();
    }
    public class ConcreteProduct1 : AbstractProduct1
    {
        public override void method2()
        {
            //业务逻辑处理
        }
        public  void method1()
        {
            //业务逻辑处理
        }
    }
    public class ConcreteProduct2 : AbstractProduct2
    {
        public override void method2()
        {
            //业务逻辑处理
        }
        public void method1()
        {
            //业务逻辑处理
        }
    }
    public abstract class AbstractFactory
    {
        //有几个产品簇的工厂就有几个实现方法
        public abstract AbstractProduct1 GetProduct1(string name);
        public abstract AbstractProduct2 GetProduct2(string name);
    }
    public class Factory1:AbstractFactory
    {
        //根据类名创建对象
        public override AbstractProduct1 GetProduct1(String name)
        {
            if (name.Equals("ConcreteProduct1", StringComparison.CurrentCultureIgnoreCase)) return new ConcreteProduct1();
            return null;
        }
    }
    public class Factory2 : AbstractFactory
    {
        //根据类名创建对象
        public override AbstractProduct2 GetProduct2(String name)
        {
            if (name.Equals("ConcreteProduct2", StringComparison.CurrentCultureIgnoreCase)) return new ConcreteProduct2();
            return null;
        }
    }
    public class FactoryCreator    //创建工厂的类
    {
        //根据类名创建对象
        public static AbstractFactory GetFactory(String name)
        {
            if (name.Equals("Factory1", StringComparison.CurrentCultureIgnoreCase)) return new Factory1();
            if (name.Equals("Factory2", StringComparison.CurrentCultureIgnoreCase)) return new Factory2();
            return null;
        }
    }
    public class Client
    {
        public static void Main(string[] args)
        {
            //AbstractFactory factory1 = new Factory1();
            //AbstractFactory factory2 = new Factory2();
            AbstractFactory factory1 = FactoryCreator.GetFactory("Factory1");
            AbstractFactory factory2 = FactoryCreator.GetFactory("Factory2");
            ConcreteProduct1 p1 = factory1.GetProduct1("concreteproduct1") as ConcreteProduct1;
            ConcreteProduct2 p2 = factory2.GetProduct2("concreteproduct2") as ConcreteProduct2;
        }
    }

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

注意事项:产品族难扩展(改动太大,不符合开闭原则),产品等级易扩展。

  • 单例模式(Singleton Pattern)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。


c#  public class Singleton
    {
        private static Singleton instance = new Singleton();
        private Singleton() { }
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
        public void ShowMessage()
        {
            Console.WriteLine("this is a singleObject");
        }
    }
    public class Client
    {
        static void Main(string[] args)
        {
            Singleton.Instance.ShowMessage();
        }
    }

优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 

            2、避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。当前是线程不安全的。


  • 建造者模式(Builder Pattern)
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

    public class Product
    {
        public void doSomething()
        {
            //独立业务处理
        }
    }
    public abstract class Builder
    {
        public abstract void setPart();//设置产品的不同部分,以获得新的产品
        public abstract Product buildProduct();//建造产品
    }
    public class ConcreteBuilder:Builder
    {
        private Product product = new Product();
        //设置产品零件
        public override void setPart()
        {
            //产品类内的逻辑处理
        }
        //组建一个产品
        public override Product buildProduct()
        {
            return product;
        }
    }
    public class Director
    {
        private Builder builder = new ConcreteBuilder();
        //构建不同的产品
        public Product getAProduct()
        {
            builder.setPart();
            //设置不同的零件,产生不同的产品
            return builder.buildProduct();
        }
    }
    public class Client
    {
        static void Main(string[] args)
        {
            Director director = new Director();
            Product product = director.getAProduct();
        }
    }

优点: 1、建造者独立,易扩展。 

            2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。

            2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。与模版方法模式结合使用更佳(产品类中使用模版方法)


  • 原型模式(Prototype Pattern)

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。


    public class Client
    {
        static void Main(string[] args)
        {
            Prototype pt1 = new Prototype();
            Prototype pt2 = (Prototype)pt1.Clone();
            Console.WriteLine(pt2.name);
        }
    }
    public class Prototype : ICloneable    //实现接口
    {
        public string name = "ssss";
        public object Clone()
        {
            object obj = null;
            try
            {
                obj = this.MemberwiseClone();//浅拷贝
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //异常处理
            }
            return obj;
        }
    }

优点: 1、性能提高。 2、逃避构造函数的约束。

缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 ICloneable 接口。

使用场景: 1、资源优化场景。 2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 3、性能和安全要求的场景。 4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5、一个对象多个修改者的场景。 6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。 7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。

注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 ICloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值