常用的创建型设计模式(C#举例)


单例模式

单例模式用于创建唯一对象,新开了两篇文章单独来写了:

  1. 基础单例模式(C#举例)
  2. 单例模式攻防进阶(C#举例)

工厂模式

当对象的创建逻辑比较复杂的时候,可以考虑使用工厂模式,封装对象的创建过程,将对象的创建和使用相分离。

  1. 代码中存在 if-else 分支判断,动态地根据不同的类型创建不同的对象
  2. 工厂方法:单个对象本身的创建过程比较复杂,比如前面提到的要组合其他类对象,做各种初始化操作等
  3. 简单工厂:适用于对象创建比较简单的情况,比如只需要用new创建
interface IRunner
{
    void Move();
}
class DemoClass
{//普通写法
    public IRunner GetRunner(string type)
    {
        IRunner runner = null;
        if (type = "marathon")
        {
            runner = new Marathon();
        }
        else if (type = "crosscountry")
        {
            runner = new Crosscountry();
        }
        else
        {
            throw new IllegalArgumentException("...")
        }
    }
}
//=============================简单工厂模式=====================
class DemoClass
{//简单工厂
    public IRunner GetRunner(string type)
    {
        IRunner runner = DemoSimpleFactory.CreateRunner(type);
        if (runner == null)
        {
            throw new IllegalArgumentException("...")
        }
    }
}
class DemoSimpleFactory1
{//简单工厂
    public static IRunner CreateRunner(string type)
    {
        IRunner runner = null;
        if (type = "marathon")
        {
            runner = new Marathon();
        }
        else if (type = "crosscountry")
        {
            runner = new Crosscountry();
        }
        return runner;
    }
}
class DemoSimpleFactory2
{//简单工厂
    private static Dictionary<string, IRunner> cachedRunner = new Dictionary<string, IRunner>();
    cachedRunner.Add("marathon", new Marathon());
    cachedRunner.Add("crosscountry", new Crosscountry());
    public static IRunner CreateRunner(string type)
    {
        return cachedRunner[type.ToLower()];
    }
}
//=============================工厂方法模式=====================
// 当然下面的工厂方法,可以继续使用简单工厂模式,来优化if-else的逻辑
class DemoClass
{//工厂方法
    public IRunner GetRunner(string type)
    {
        IRunnerFactory runnerFactory
        if (type == "marathon")
        {
            runner = new DemoMarathonFactory();
        }
        else if (type == "crosscountry")
        {
            runner = new DemoCrossCountryFactory();
        }
        else
        {
            throw new IllegalArgumentException("...")
        }

        IRunner runner = runnerFactory.createRunner();
    }
}
public interface IRunnerFactory
{ //工厂方法
    IRunner createRunner();
}
class DemoMarathonFactory : IRunnerFactory
{//工厂方法
    public IRunner createRunner()
    {
        return new Marathon();
    }
}
class DemoCrossCountryFactory : IRunnerFactory
{//工厂方法
    public IRunner createRunner()
    {
        return new Crosscountry();
    }

}


建造者模式

如果一个类中有很多属性,为了避免构造函数的参数列表过长,影响代码的可读性和易用性,可以通过构造函数配合 set 方法来解决。
但是,如果存在下面情况中的任意一种,可以使用建造者模式:

  1. 我们把类的必填属性放到构造函数中,强制创建对象的时候就设置
  2. 必填的属性有很多时,如果在构造函数中,那参数列表就会很长,如果属性通过 set 方法设置,那无法校验必填属性是否已经填写
  3. 类的属性之间有一定的依赖关系或约束条件
  4. 希望创建不可变对象,即对象在创建好之后,就不能再修改时,就不能暴露 set 方法
public class UserInfo
{
    private long Id;
    private String name;    //用户名
    private String password; //密码
    private String email;
    private String phone;
    private long lastLoginTime;
    private String province; // 省
    private String city; // 市
    private String region; // 区 
    private String address; // 详细地址

    private UserInfo(Builder builder)
    {//静态构造函数
        this.Id = builder.Id;
        this.name = builder.name;
        this.password = builder.password;
        this.email = builder.email;
        //...
    }
    //...省略getter方法...

    //将Builder类设计成了UserInfo的内部类。
    //也可以将Builder类设计成独立的非内部类UserInfoBuilder。
    public static class Builder
    {
        private long Id;
        private String name;    //用户名
        private String password; //密码
        private String email;
        private String phone;
        private long lastLoginTime;
        private String province; // 省
        private String city; // 市
        private String region; // 区 
        private String address; // 详细地址

        public UserInfo build()
        {
            // 校验逻辑放到这里来做,包括必填项校验、依赖关系校验、约束条件校验等
            if (name.equals(password))
            {
                throw new IllegalArgumentException("...");
            }
            //...其它关联校验

            return new UserInfo(this);
        }

        public Builder setName(String name)
        {//单独校验
            if (name.Equal(String.Empity))
            {
                throw new IllegalArgumentException("...");
            }
            this.name = name;
            return this;
        }

        public Builder setPassword(String password)
        {//单独校验
            if (password.Equal(String.Empity))
            {
                throw new IllegalArgumentException("...");
            }
            if (password.Length < 8)
            {
                throw new IllegalArgumentException("...");
            }

            this.password = password;
            return this;
        }
        //...其它参数设置
    }
}

UserInfo user = new UserInfo.Builder()
        .setName("suoxd123")
        .setPassword(“suoxd123456”)
        //其它参数
        .build();

原型模式

基于原型来创建对象的方式就叫作原型设计模式。

如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式,来创建新对象,以达到节省创建时间的目的。

原型模式的两种实现方法原型模式有两种实现方法,深拷贝和浅拷贝。

  1. 浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址
  2. 深拷贝递归地复制引用对象,以及引用对象的引用对象,更加耗时,更加耗内存空间。

汇总说明

  1. 单例模式用来创建全局唯一的对象;
  2. 工厂模式用来创建不同但是相关类型的对象,由给定的参数来决定创建哪种类型的对象;
  3. 建造者模式是用来创建复杂对象,可以通过设置不同的可选参数,“定制化”地创建不同的对象;
  4. 原型模式针对创建成本比较大的对象,利用对已有对象进行复制的方式进行创建,以达到节省创建时间的目的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放羊郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值