同样不是怎么高深的或者新的东西,只是一种编程方式,甚至可以说只是编程风格而已。
只是抽象工厂模式的编程风格得到广泛应用,你不了解一下,还真看不懂。
抽象工厂模式就是,多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。即提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。
举个例子还说明,就相当于一个奶茶店的老板,他要生产小杯奶茶、大杯奶茶、小杯咖啡、大杯咖啡给顾客,他的生产流程就生产奶茶、咖啡,然后再生成小杯、大杯,最后将两个过程最终合在一起就是产品,不是说这4样东西都是孤立的,他要修改小杯的尺寸,修改完后,就能够直接修改小杯奶茶、小杯咖啡,不会孤立地分别修改。
比如如下一段经典JAVA的代码,不同的厂商分别生产各自的手机。而这些手机都有共同的method接口,一目了然地可以发现,不同的method接口的实现是不一样的。
//定义不同的产品之间的一定具备的标准,用interface实现
//其中的method()方法可看作提取出不同产品的共性,如手机都有类似的功能
interface IProductA {
public void method();
}
interface IProductB {
public void method();
}
// 实现了产品标准实现的一系列具体产品
// 由于已经设计好A1由厂商1生产,故以下输出代码有“厂商x”
class ProductA1 implements IProductA {
public void method() {
System.out.println("厂商1 生产ProductA1 ...");
}
}
class ProductA2 implements IProductA {
public void method() {
System.out.println("厂商2 生产ProductA2 ...");
}
}
class ProductB1 implements IProductB {
public void method() {
System.out.println("厂商1 生产ProductB1 ...");
}
}
class ProductB2 implements IProductB {
public void method() {
System.out.println("厂商2 生产ProductB2 ...");
}
}
// 每一种牌子的产品生产工厂,即不同的厂商负责自己牌子产品的生产
abstract class Factory1 {
abstract IProductA getProductA1();
abstract IProductB getProductB1();
}
abstract class Factory2 {
abstract IProductA getProductA2();
abstract IProductB getProductB2();
}
// 具体的工厂用来生产相关的产品
class ConcreteFactory1 extends Factory1 {
public IProductA getProductA1() {
return new ProductA1();
}
public IProductB getProductB1() {
return new ProductB1();
}
}
class ConcreteFactoryB extends Factory2 {
public IProductA getProductA2() {
return new ProductA2();
}
public IProductB getProductB2() {
return new ProductB2();
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 厂商1负责生产产品A1、B1
Factory1 factory1 = new ConcreteFactory1();
IProductA productA1 = factory1.getProductA1();
IProductB productB1 = factory1.getProductB1();
productA1.method();
productB1.method();
// 厂商2负责生产产品A2、B2
Factory2 factory2 = new ConcreteFactoryB();
IProductA productA2 = factory2.getProductA2();
IProductB productB2 = factory2.getProductB2();
productA2.method();
productB2.method();
}
}
再用一道2012年下半年软件设计师的软考题来说明这个问题:
题目是这样的:现欲开发一个软件系统,要求能够同时支持多种不同的数据库,为此采用抽象工厂模式设计该系统,以SQL Server和Access两种数据库以及系统中的数据库表Department为例,其类图如图6-1所示:
具体的Java实现代码如下所示:
//创造、实现方法。
class Department {
// 根据数据库中Department表所建立的实体类
}
interface IDepartment {
public void Insert(Department department);
public Department GetDepartment(int id);
}
class SqlServerDepartment implements IDepartment {
@Override
public void Insert(Department department) {
System.out.println("插入Department到Sqlserver");
// 实现插入Department到Sqlserver的代码
}
@Override
public Department GetDepartment(int id) {
System.out.println("得到Sqlserver的id为" + id + "的Department");
// 实现从Sqlserver得到Department的代码
return null;
}
}
class AccessDepartment implements IDepartment {
@Override
public void Insert(Department department) {
System.out.println("插入Department到Access");
// 实现插入Department到Access的代码
}
@Override
public Department GetDepartment(int id) {
System.out.println("得到Access的id为" + id + "的Department");
return null;
// 实现从Access得到Department的代码
}
}
// 创造类
interface IFactory {
public IDepartment createDepartment();
}
class SqlServerFactory implements IFactory {
@Override
public IDepartment createDepartment() {
return new SqlServerDepartment();
}
}
class AccessFactory implements IFactory {
@Override
public IDepartment createDepartment() {
return new AccessDepartment();
}
}
public class AbstractFactoryTest {
public static void main(String[] args) {
Department department = new Department();
SqlServerFactory sqlServerFactory = new SqlServerFactory();
sqlServerFactory.createDepartment().Insert(department);
sqlServerFactory.createDepartment().GetDepartment(1);
AccessFactory accessFactory = new AccessFactory();
accessFactory.createDepartment().Insert(department);
accessFactory.createDepartment().GetDepartment(6);
}
}
运行结果如下所示:
这个程序,是从下面看到上面的,可以看到主函数,只是实例化了工厂,你要搞Sql Server就新建Sql Server工厂,要搞Access就新建Access工厂,
之后无论是什么工厂利用其createDepartment()方法,建立相应类,具体看上面创建类的部分,
一个接口,同名方法createDepartment(),根据工厂的不同,实现方法是不同的,就是返回不同的类。相当于一开始例子中的“奶茶”还是“咖啡”
之后,再调用里面的Insert()方法与GetDepartment(),此两个方法的实现,见最上面的创造、实现方法部分。
不同的类里面,这两个方法的实现是不同的,相当于一开始例子中的“小杯奶茶”还是“大杯奶茶”,或者是“小杯咖啡”还是“大杯咖啡”。形成了1:2:4:n的关系。
然而主函数的实现是很清晰的。