简单工厂模式是在什么场景下使用呢,下面就以本人的理解举例说明:
就拿登录功能来说,假如应用系统需要支持多种登录方式如:口令认证、域认证(口令认证
通常是去数据库中验证用户,而域认证则是需要到微软的域中验证用户)。那么自然的做法就是
建立一个各种登录方式都适用的接口,如下图所示:
publicinterface Login {
//登录验证
publicboolean verify(String name , String password);
}
publicclass DomainLogin implements Login {
@Override
publicboolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
returntrue;
}
}
publicclass PasswordLogin implements Login {
@Override
publicboolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
returntrue;
}
}
我们还需要一个工厂类LoginManager,根据调用者不同的要求,创建出不同的
登录对象并返回。而如果碰到不合法的要求,会返回一个Runtime异常。
publicclass LoginManager {
publicstatic Login factory(String type){
if(type.equals("password")){
returnnew PasswordLogin();
}elseif(type.equals("passcode")){
returnnew DomainLogin();
}else{
/**
* 这里抛出一个自定义异常会更恰当
*/
thrownew RuntimeException("没有找到登录类型");
}
}
}
测试类:
publicclass Test {
publicstaticvoid main(String[] args) {
// TODO Auto-generated method stub
String loginType = "password";
String name = "name";
String password = "password";
Login login = LoginManager.factory(loginType);
boolean bool = login.verify(name, password);
if (bool) {
/**
* 业务逻辑
*/
} else {
/**
* 业务逻辑
*/
}
}
}
简单工厂模式的结构如下图:
我们可以设想一下真实的场景,如果把上面的Test当做一个servlet的话,当客户
端发起登录请求——>请求交给服务端的Servlet——>Servlet根据客户端传递的
loginType调用工厂类LoginManager的factory()方法——>factory()方法根据
参数loginType创建相应的登录验证类(DomainLogin或PasswordLogin)并返回
——>登录验证类调用方法verify()验证用户名密码是否正确
简单工厂模式的优点
模式的核心是工厂类。这个类含有必要的逻辑判断,可以决定在什么时候创建哪一个登录验
证类的实例,而调用者则可以免除直接创建对象的责任。简单工厂模式通过这种做法实现了对责
任的分割,当系统引入新的登录方式的时候无需修改调用者。
简单工厂模式的缺点
这个工厂类集中了所以的创建逻辑,当有复杂的多层次等级结构时,所有的业务逻辑都在这
个工厂类中实现。什么时候它不能工作了,整个系统都会受到影响。
UML类图的一些知识: 类图分三层,第一层显示类的名称,如果是抽象类,则用斜体表示,第二层是类的特性,通常就
是字段和属性,第三层是类的操作,通常就是方法或行为。在他们前面的“+”表示
public,“-”表示private“#”表示protected
继承用空心三角形+实线来表示,当一个类'知道'另外一个类的时候用关联,关联用实线箭头来表示。 聚合表示的是一种弱的拥有关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分,聚合关系用空心的灵性+实线箭头来表示。 合成(也叫组合)是一种强的拥有关系,体现了严格的部分和整体的关系,整体和部分的关系的生命周期一样。合成关系的连线两端还有shu,这些被称为基数,表明这一端可以有多少个类。 依赖关系用虚线箭头表示。
工厂方法模式的用意是定义一个创建XX对象的工厂接口,将实际创建工作推迟到子类中。
首先,在工厂方法模式中,核心的工厂类不再负责生产所有的产品的创建,而是将具体创建的工
厂工作交给子类去做,这个核心类则成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现
的接口,而不接触哪一个产品类应该被实例化这种细节。
•工厂类(Creator)角色:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业
逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体Java 类实现。
public class Creator
{
public static Product factory()
{
return new ConcreteProduct();
}
}
•抽象产品(Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们
共同拥有的接口。抽象产品角色可以用一个Java 接口或者Java 抽象类实现。
public interface Product
{
}
•具体产品(Concrete Product)角色:工厂方法模式所创建的任何对象都是这个角色的实例,
具体产品角色由一个具体Java 类实现。
public class ConcreteProduct implements Product
{
public ConcreteProduct(){}
}
•与简单工厂模式中的情形一样的是,ConcreteCreator的factory() 方法返还的数据类型是一个抽象类型Product,而不是哪一个具体产品类型,而客户端也不必知道所得到的产品的真实类
型。这种多态性设计将工厂类选择创建哪一个产品对象、如何创建这个对象的细节完全封装在具
体工厂类内部。
•对于增加新的产品类而言,这个系统完全支持“开-闭”原则。
•简单工厂角色只在有限的程度上支持“开–闭”原则。