二. 工厂模式
整理自 《java与模式》阎宏编著
简单工厂模式
1.意图:
由一个工厂类根据传入的参数来决定要创建哪一个产品类的实例。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10021/47201137-4169-3911-a2e7-620fe09ddeda.jpg[/img]
3.原理:
由一个工厂类根据传入的参数来决定要创建哪一个产品类的实例,由于工厂方法返回的对象是抽象类型或接口而不是类,因此工厂能返回接口的任何实现。
将系统划分为产品消费者角色(client),产品工厂角色(factory),和产品角色(product)。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10023/0febf582-9a3a-3a74-b7f5-12743c435140.jpg[/img]
每新增一个新产品,对于产品消费者角色可以不用对现有的代码的进行修改,满足“开-闭”原则,对于产品工厂则必须修改现在的代码,不满足“开-闭”原则。
4.特征:
a.该方法创建了一个新的对象.
b.该方法的返回类型为一个抽象类或接口.
c.有若干个类实现了上述的抽象类型.
5.说明:
工厂模式的优点:产品的等级结构不会反应到工厂类中来,从而使产品的等级结构的修改不会影响到工厂类的修改。
工厂模式的缺点:新增一个产品必然导致工厂方法的修改。
模式的简化:
a.抽象产品角色的省略:如果只有一个产品,则可以省略抽象产品。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10025/545c18fa-d61a-3205-b222-207f2508530e.jpg[/img]
b.工厂类角色与抽象产品角色合并:将工厂方法放在抽象产品类中。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10027/1ba79864-8ff4-38c5-b381-52333db16a05.jpg[/img]
c. 工厂类角色,具体工厂角色和抽象产品角色合并, 如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10029/e161d074-cc65-3755-982d-e2618ee2b8b4.jpg[/img]
6.使用案例:
7.代码:
// AbstractProduct.java
//抽象产品
public interface AbstractProduct
{
}
// ConcreteProduct1.java
//具体产品1
public class ConcreteProduct1 implements AbstractProduct
{
}
// ConcreteProduct2.java
//具体产品2
public class ConcreteProduct2 implements AbstractProduct
{
}
// SimpleProductFactory.java
//工厂方法类
public class SimpleProductFactory
{
public static AbstractProduct factoryMethod(String para)
{
if ("product1".equals(para))
return new ConcreteProduct1();
else if ("product2".equals(para))
return new ConcreteProduct2();
else
return null;
/*
//也可以通过外部配置文件来动态创建具体实例
String className = System.getProperty("product");
AbstractProduct pro = (AbstractProduct) Class.forName(className).newInstance();
return pro;
*/
}
}
工厂方法模式(多态工厂方法)
1.意图:
定义一个创建产品对象的接口,将实际创建的工作延迟到其子类。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10039/e442c050-e19b-3525-9f25-51d5b3781135.jpg[/img]
3.原理:
抽象工厂类定义了创建产品对象的方法接口,具体的创建工作由具体工厂子类去实现,这种进一步抽象化的结果,使这种工厂方法模式允许系统在不修改具体工厂角色的情况下引进新的产品。系统引进一个新产品,只需要在系统中加入这一产品类和它所对应的工厂类,没必要修改抽象工厂角色以及已经存在的具体工厂。对增加新的产品类而言完全满足“开-闭”原则。
4.特征:
a.抽象工厂类定义了创建产品对象的方法接口.
b.具体工厂类实现了抽象工厂类中定义的方法并负责创建具体的产品类对象.
c.该方法的返回类型为一个抽象的产品类或接口.
d.有若干个类实现了上述的抽象产品类或接口.
5.说明:
6.使用案例:
7.代码:
// AbstractProduct.java
//抽象产品
public interface AbstractProduct
{
}
// ConcreteProduct1.java
//具体产品1
public class ConcreteProduct1 implements AbstractProduct
{
}
// ConcreteProduct2.java
//具体产品2
public class ConcreteProduct2 implements AbstractProduct
{
}
// AbstractFactory.java 抽象工厂类
public abstract class AbstractFactory
{
public abstract AbstractProduct factoryMethod();
}
// ConcreteFactory1.java 具体工厂类
public class ConcreteFactory1 extends Abstract Factory
{
public AbstractProduct factoryMethod()
{
return new ConcreteProduct1();
}
}
// ConcreteFactory2.java 具体工厂类
public class ConcreteFactory2 extends Abstract Factory
{
public AbstractProduct factoryMethod()
{
return new ConcreteProduct2();
}
}
//产品消费者
public class Client
{
private static AbstractProduct product1 = null;
private static AbstractProduct product2 = null;
private static Abstract Factory creator1 = null;
private static Abstract Factory creator2 = null;
public void main(String[] args)
{
creator1 = new Concrete Factory1();
product1 = creator1.factoryMethod();
creator2 = new Concrete Factory2();
product2 = creator2.factoryMethod();
}
}
抽象工厂方法模式
1.意图:
向客户端提供一个接口,使用客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10037/fa40d03e-418c-35ce-a4dd-c612246a316c.jpg[/img]
3.原理:
在产品等级结构不变情况下,增加新的产品族,只需要增加一个新的具体工厂,而无需修改现有的具体工厂和产品角色,所以对增加产品族而言,满足“开-闭”原则。
在产品族数目不变情况下,增加新的产品等级结构,需要修改所有的具体工厂,增加新的创建产品的工厂方法。不满足“开-闭”原则。
4.特征:
a.为每一族产品对象提供一个创建新产品的具体工厂类.
5.说明:
6.使用案例:
Windows的视窗部件和Linux的视窗部件属于两个不同的类别。可以定义两个不同的工厂WinFactory和LinuxFactory分别创建各自的视窗部件。如图:
[img]http://eneasy.iteye.com/upload/picture/pic/10035/eefcc015-1ca9-3df6-b3a7-6b209196c86e.jpg[/img]
7.代码:
整理自 《java与模式》阎宏编著
简单工厂模式
1.意图:
由一个工厂类根据传入的参数来决定要创建哪一个产品类的实例。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10021/47201137-4169-3911-a2e7-620fe09ddeda.jpg[/img]
3.原理:
由一个工厂类根据传入的参数来决定要创建哪一个产品类的实例,由于工厂方法返回的对象是抽象类型或接口而不是类,因此工厂能返回接口的任何实现。
将系统划分为产品消费者角色(client),产品工厂角色(factory),和产品角色(product)。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10023/0febf582-9a3a-3a74-b7f5-12743c435140.jpg[/img]
每新增一个新产品,对于产品消费者角色可以不用对现有的代码的进行修改,满足“开-闭”原则,对于产品工厂则必须修改现在的代码,不满足“开-闭”原则。
4.特征:
a.该方法创建了一个新的对象.
b.该方法的返回类型为一个抽象类或接口.
c.有若干个类实现了上述的抽象类型.
5.说明:
工厂模式的优点:产品的等级结构不会反应到工厂类中来,从而使产品的等级结构的修改不会影响到工厂类的修改。
工厂模式的缺点:新增一个产品必然导致工厂方法的修改。
模式的简化:
a.抽象产品角色的省略:如果只有一个产品,则可以省略抽象产品。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10025/545c18fa-d61a-3205-b222-207f2508530e.jpg[/img]
b.工厂类角色与抽象产品角色合并:将工厂方法放在抽象产品类中。如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10027/1ba79864-8ff4-38c5-b381-52333db16a05.jpg[/img]
c. 工厂类角色,具体工厂角色和抽象产品角色合并, 如下图:
[img]http://eneasy.iteye.com/upload/picture/pic/10029/e161d074-cc65-3755-982d-e2618ee2b8b4.jpg[/img]
6.使用案例:
7.代码:
// AbstractProduct.java
//抽象产品
public interface AbstractProduct
{
}
// ConcreteProduct1.java
//具体产品1
public class ConcreteProduct1 implements AbstractProduct
{
}
// ConcreteProduct2.java
//具体产品2
public class ConcreteProduct2 implements AbstractProduct
{
}
// SimpleProductFactory.java
//工厂方法类
public class SimpleProductFactory
{
public static AbstractProduct factoryMethod(String para)
{
if ("product1".equals(para))
return new ConcreteProduct1();
else if ("product2".equals(para))
return new ConcreteProduct2();
else
return null;
/*
//也可以通过外部配置文件来动态创建具体实例
String className = System.getProperty("product");
AbstractProduct pro = (AbstractProduct) Class.forName(className).newInstance();
return pro;
*/
}
}
工厂方法模式(多态工厂方法)
1.意图:
定义一个创建产品对象的接口,将实际创建的工作延迟到其子类。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10039/e442c050-e19b-3525-9f25-51d5b3781135.jpg[/img]
3.原理:
抽象工厂类定义了创建产品对象的方法接口,具体的创建工作由具体工厂子类去实现,这种进一步抽象化的结果,使这种工厂方法模式允许系统在不修改具体工厂角色的情况下引进新的产品。系统引进一个新产品,只需要在系统中加入这一产品类和它所对应的工厂类,没必要修改抽象工厂角色以及已经存在的具体工厂。对增加新的产品类而言完全满足“开-闭”原则。
4.特征:
a.抽象工厂类定义了创建产品对象的方法接口.
b.具体工厂类实现了抽象工厂类中定义的方法并负责创建具体的产品类对象.
c.该方法的返回类型为一个抽象的产品类或接口.
d.有若干个类实现了上述的抽象产品类或接口.
5.说明:
6.使用案例:
7.代码:
// AbstractProduct.java
//抽象产品
public interface AbstractProduct
{
}
// ConcreteProduct1.java
//具体产品1
public class ConcreteProduct1 implements AbstractProduct
{
}
// ConcreteProduct2.java
//具体产品2
public class ConcreteProduct2 implements AbstractProduct
{
}
// AbstractFactory.java 抽象工厂类
public abstract class AbstractFactory
{
public abstract AbstractProduct factoryMethod();
}
// ConcreteFactory1.java 具体工厂类
public class ConcreteFactory1 extends Abstract Factory
{
public AbstractProduct factoryMethod()
{
return new ConcreteProduct1();
}
}
// ConcreteFactory2.java 具体工厂类
public class ConcreteFactory2 extends Abstract Factory
{
public AbstractProduct factoryMethod()
{
return new ConcreteProduct2();
}
}
//产品消费者
public class Client
{
private static AbstractProduct product1 = null;
private static AbstractProduct product2 = null;
private static Abstract Factory creator1 = null;
private static Abstract Factory creator2 = null;
public void main(String[] args)
{
creator1 = new Concrete Factory1();
product1 = creator1.factoryMethod();
creator2 = new Concrete Factory2();
product2 = creator2.factoryMethod();
}
}
抽象工厂方法模式
1.意图:
向客户端提供一个接口,使用客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。
2.类图:
[img]http://eneasy.iteye.com/upload/picture/pic/10037/fa40d03e-418c-35ce-a4dd-c612246a316c.jpg[/img]
3.原理:
在产品等级结构不变情况下,增加新的产品族,只需要增加一个新的具体工厂,而无需修改现有的具体工厂和产品角色,所以对增加产品族而言,满足“开-闭”原则。
在产品族数目不变情况下,增加新的产品等级结构,需要修改所有的具体工厂,增加新的创建产品的工厂方法。不满足“开-闭”原则。
4.特征:
a.为每一族产品对象提供一个创建新产品的具体工厂类.
5.说明:
6.使用案例:
Windows的视窗部件和Linux的视窗部件属于两个不同的类别。可以定义两个不同的工厂WinFactory和LinuxFactory分别创建各自的视窗部件。如图:
[img]http://eneasy.iteye.com/upload/picture/pic/10035/eefcc015-1ca9-3df6-b3a7-6b209196c86e.jpg[/img]
7.代码: