什么是工廠模式
工廠模式是最常用的設計模式之一,屬于創建型模式,
有點:
- 解耦,可以把物件的創建和程序分開
- 減少代碼量,易于維護
什么時候用?
當一個抽象類有多個實作的時候,需要多次實體化的時候,就要考慮使用工廠模式,
比如:登錄的抽象類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<T>是從當前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);
}
郵箱:[email protected]QQ:785418
微信:jamesying1
QQ群:376248054 通關:cnblogs
技術改變生活,技術改變人生!用技術來創造價值,擁有技術,不僅僅是開發,您將獲得更多!如果您覺得我能幫到您,您可以通過掃描下面二維碼來【捐助】我!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/495598.html
標籤:.NET技术
