什么是工厂模式
工厂模式是最常用的设计模式之一,属于创建型模式。
有点:
- 解耦,可以把对象的创建和过程分开
- 减少代码量,易于维护
什么时候用?
当一个抽象类有多个实现的时候,需要多次实例化的时候,就要考虑使用工厂模式。
比如:登录的抽象类ILoginBusiness,它有2个实现,一个用用户名密码登录,一个用手机号验证码登录- public interface ILoginBusiness
- {
- Task Login(LoginInputDTO input);
- }
- public class MobileCodeLogin : ILoginBusiness
- {
- public Task Login(LoginInputDTO input)
- {
- // todo
- }
- }
- public class UserNameAndPasswordLogin : ILoginBusiness
- {
- public Task Login(LoginInputDTO input)
- {
- // todo
- }
- }
复制代码 按照原有方式,我们会根据某个条件去实例化,比如loginType- ILoginBusiness loginBusiness;
- if (loginType == 1)
- {
- loginBusiness = new MobileCodeLogin();
- }
- else
- {
- loginBusiness = new UserNameAndPasswordLogin()
- }
复制代码 当有多种实例的话,就需要更多的ifelse或者switch,工厂模式的作用就是把这种建造对象的方法放在工厂类去解决,统一管理统一维护。
实现方式
- public interface ILoginFactory
- {
- ILoginBusiness Create(LoginInputDTO inputDto);
- }
- public class LoginFactory : BaseBusiness, ILoginFactory, ITransientDependency
- {
-
- public ILoginBusiness Create(LoginInputDTO inputDto)
- {
- return inputDto.LoginType == LoginType.UserNameAndPwd
- ? AppDependencyResolver.Current.GetService<UserNameAndPwdLogin>()
- : (ILoginBusiness)AppDependencyResolver.Current.GetService<MobileCodeLogin>();
- }
- public LoginFactory(IRepository repository) : base(repository)
- {
-
- }
- }
复制代码 如果用new的方法去实例化,就需要把构造方法中的参数在工厂的构造方法里也加入进去,所以这里用了一个AppDependencyResolver,这里的AppDependencyResolver.Current.GetService是从当前IOC容器中获取注入的实例,所以之前的MobileCodeLogin和UserNameAndPasswordLogin需要注入到IOC实例中,在我们项目就是继承ITransientDependency- public class AppDependencyResolver
- {
- private static AppDependencyResolver _resolver;
- public static AppDependencyResolver Current
- {
- get
- {
- if (_resolver == null)
- throw new Exception("AppDependencyResolver not initialized");
- return _resolver;
- }
- }
-
- // 在startUp的ConfigureService的最后,加入AppDependencyResolver.Init(services.BuildServiceProvider());
- public static void Init(IServiceProvider service)
- {
- _resolver = new AppDependencyResolver(service);
- }
- private AppDependencyResolver(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
- private readonly IServiceProvider _serviceProvider;
- public object GetService(Type serviceType)
- {
- return _serviceProvider.GetService(serviceType);
- }
- public T GetService<T>()
- {
- return _serviceProvider.GetService<T>();
- }
- }
复制代码 关于工厂的单元测
关于工厂,我们只需要测返回的对象是否是我们需要的就可以了,至于对象的执行对不对不需要关心- [Theory(DisplayName = "测试登录工厂")]
- [InlineData(LoginType.MobileCode, typeof(MobileCodeLogin))]
- [InlineData(LoginType.UserNameAndPwd, typeof(UserNameAndPwdLogin))]
- public void CreateTests(LoginType loginType, Type expectedType)
- {
- Mock<IRepository> mock = new Mock<IRepository>();
- ILoginFactory factory = new LoginFactory(mock.Object);
- var login = factory.Create(new LoginInputDTO()
- {
- LoginType = loginType
- });
- Assert.IsType(expectedType, login);
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |