赞
踩
简单工厂模式包含如下角色:
以登录功能来说,假如应用系统需要支持多种登录方式如:口令认证、域认证(口令认证通常是去数据库中验证用户,而域认证则是需要到微软的域中验证用户)。
那么自然的做法就是建立一个各种登录方式都适用的接口,如下图所示:
抽象产品Login:
public interface Login {
//登录验证
public boolean verify(String name , String password);
}
具体产品DomainLogin
public class DomainLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
}
}
具体产品PasswordLogin
public class PasswordLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
}
}
工厂类LoginManager
根据调用者不同的要求,创建出不同的登录对象并返回。而如果碰到不合法的要求,会返回一个Runtime异常。
public class LoginManager {
public static Login factory(String type){
if(type.equals("password")){
return new PasswordLogin();
}else if(type.equals("passcode")){
return new DomainLogin();
}else{
/**
* 这里抛出一个自定义异常会更恰当
*/
throw new RuntimeException("没有找到登录类型");
}
}
}
测试:
public class Test { public static void main(String[] args) { String loginType = "password"; String name = "name"; String password = "password"; Login login = LoginManager.factory(loginType); boolean bool = login.verify(name, password); if (bool) { /** * 业务逻辑 */ } else { /** * 业务逻辑 */ } } }
假如不使用简单工厂模式则验证登录Servlet代码如下:
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String loginType = "password"; String name = "name"; String password = "password"; //处理口令认证 if(loginType.equals("password")){ PasswordLogin passwordLogin = new PasswordLogin(); boolean bool = passwordLogin.verify(name, password); if (bool) { /** * 业务逻辑 */ } else { /** * 业务逻辑 */ } } //处理域认证 else if(loginType.equals("passcode")){ DomainLogin domainLogin = new DomainLogin(); boolean bool = domainLogin.verify(name, password); if (bool) { /** * 业务逻辑 */ } else { /** * 业务逻辑 */ } }else{ /** * 业务逻辑 */ } } }
可以看到非常麻烦,代码重复很多,而且不利于扩展维护。
优点:
缺点:
适用环境:
不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成。
工厂方法模式包含如下角色:
小明(客户端)想要买一个灯泡,他不认识工厂,只能去供销店(工厂类)买,
于是和老板说“我要一个灯泡”老板说“没问题!您稍等”。
转身到了后院,对生产灯泡的小弟(灯泡工厂子类)吆喝一声,给我造个灯泡!
不一会灯泡造好了,老板拿给小明,“嘿嘿,灯泡给您作了一个,您试试?”
小明把灯泡拧在灯口上,开关了两下(灯的通用方法)“嘿!挺好,没问题!”,付了钱高高兴兴走了。
抽象的产品接口ILight
public interface ILight
{
void TurnOn();
void TurnOff();
}
具体的产品类:BulbLight
public class BulbLight implements ILight
{
public void TurnOn()
{
Console.WriteLine("BulbLight turns on.");
}
public void TurnOff()
{
Console.WriteLine("BulbLight turns off.");
}
}
具体的产品类:TubeLight
public class TubeLight implements ILight
{
public void TurnOn()
{
Console.WriteLine("TubeLight turns on.");
}
public void TurnOff()
{
Console.WriteLine("TubeLight turns off.");
}
}
抽象的工厂类
public interface ICreator
{
ILight CreateLight();
}
具体的工厂类:BulbCreator
public class BulbCreator implements ICreator
{
public ILight CreateLight()
{
return new BulbLight();
}
}
具体的工厂类:TubeCreator
public class TubeCreator implements ICreator
{
public ILight CreateLight()
{
return new TubeLight();
}
}
客户端调用
static void Main(string[] args)
{
//先给我来个灯泡
ICreator creator = new BulbCreator();
ILight light = creator.CreateLight();
light.TurnOn();
light.TurnOff();
//再来个灯管看看
creator = new TubeCreator();
light = creator.CreateLight();
light.TurnOn();
light.TurnOff();
}
通过一个引用变量ICreator来创建产品对象,创建何种产品对象由指向的具体工厂类决定。通过工厂方法模式,将具体的应用逻辑和产品的创建分离开,促进松耦合。
本例中每个具体工厂类只负责生产一种类型的产品,当然每个具体工厂类也内部可以维护少数几种产品实例对象,类似于简单工厂模式。
优点:
缺点:
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种或几种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个不同种类产品对象,而不是单一种类的产品对象。
为了更清晰地理解工厂方法模式,需要先引入两个概念:
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
抽象工厂模式包含如下角色:
假设有一个移动终端工厂,可以制造苹果系列的移动产品和三星系列的移动产品。这个工厂下有两个子厂,一个负责制造苹果系列的Pad和三星系列的Pad,另一个负责制造苹果系列的手机和三星系列的手机。这便是一个典型的抽象工厂的实例。
抽象产品: 苹果系列:
public interface Apple
{
void AppleStyle();
}
抽象产品: 三星系列:
public interface Sumsung
{
void BangziStyle();
}
具体产品:iphone:
public class iphone implements Apple
{
public void AppleStyle()
{
Console.WriteLine("Apple's style: iPhone!");
}
}
具体产品:ipad:
public class ipad implements Apple
{
public void AppleStyle()
{
Console.WriteLine("Apple's style: iPad!");
}
}
具体产品:note2:
public class note2 implements Sumsung
{
public void BangziStyle()
{
Console.WriteLine("Bangzi's style : Note2!");
}
}
具体产品:tabs:
public class Tabs implements Sumsung
{
public void BangziStyle()
{
Console.WriteLine("Bangzi's style : Tab!");
}
}
抽象工厂:
public interface Factory
{
Apple createAppleProduct();
Sumsung createSumsungProduct();
}
手机工厂:
public class Factory_Phone implements Factory
{
public Apple createAppleProduct()
{
return new iphone();
}
public Sumsung createSumsungProduct()
{
return new note2();
}
}
Pad工厂:
public class Factory_Pad implements Factory
{
public Apple createAppleProduct()
{
return new ipad();
}
public Sumsung createSumsungProduct()
{
return new Tabs();
}
}
客户端调用:
public static void Main(string[] args) { //采购商要一台iPad和一台Tab Factory factory = new Factory_Pad(); Apple apple = factory.createAppleProduct(); apple.AppleStyle(); Sumsung sumsung = factory.createSumsungProduct(); sumsung.BangziStyle(); //采购商又要一台iPhone和一台Note2 factory = new Factory_Phone(); apple = factory.createAppleProduct(); apple.AppleStyle(); sumsung = factory.createSumsungProduct(); sumsung.BangziStyle(); Console.ReadKey(); }
抽象工厂可以通过多态,来动态设置不同的工厂,生产不同的产品,同时每个工厂中的产品又不属于同一个产品等级结构。
优点:
缺点:
①一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
②系统中有多于一个的产品族,而每次只使用其中某一产品族。与工厂方法模式的区别
③属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
④系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。