单例模式
单例模式用于创建唯一对象,新开了两篇文章单独来写了:
工厂模式
当对象的创建逻辑比较复杂的时候,可以考虑使用工厂模式,封装对象的创建过程,将对象的创建和使用相分离。
- 代码中存在 if-else 分支判断,动态地根据不同的类型创建不同的对象
- 工厂方法:单个对象本身的创建过程比较复杂,比如前面提到的要组合其他类对象,做各种初始化操作等
- 简单工厂:适用于对象创建比较简单的情况,比如只需要用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 方法来解决。
但是,如果存在下面情况中的任意一种,可以使用建造者模式:
- 我们把类的必填属性放到构造函数中,强制创建对象的时候就设置
- 必填的属性有很多时,如果在构造函数中,那参数列表就会很长,如果属性通过 set 方法设置,那无法校验必填属性是否已经填写
- 类的属性之间有一定的依赖关系或约束条件
- 希望创建不可变对象,即对象在创建好之后,就不能再修改时,就不能暴露 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();
原型模式
基于原型来创建对象的方式就叫作原型设计模式。
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式,来创建新对象,以达到节省创建时间的目的。
原型模式的两种实现方法原型模式有两种实现方法,深拷贝和浅拷贝。
- 浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址
- 深拷贝递归地复制引用对象,以及引用对象的引用对象,更加耗时,更加耗内存空间。
汇总说明
- 单例模式用来创建全局唯一的对象;
- 工厂模式用来创建不同但是相关类型的对象,由给定的参数来决定创建哪种类型的对象;
- 建造者模式是用来创建复杂对象,可以通过设置不同的可选参数,“定制化”地创建不同的对象;
- 原型模式针对创建成本比较大的对象,利用对已有对象进行复制的方式进行创建,以达到节省创建时间的目的