这里有新鲜出炉的 Java 设计模式,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要为大家详细介绍了 java 设计模式之抽像工厂的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
一,概念
提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类.
二,模式动机
这一系列对像之间是相互依赖的,相当于一个产品族
三,模式的结构
通过上图我们可以清楚的看到抽像工厂模式包括以下 4 个角色:
1. 抽像工厂角色(AbstractFactory):抽像工厂模式的核心,与具体的商业逻辑无关,通常是一个 JAVA 接口或者抽像类.
2. 具体工厂角色(Concrete Factory):该角色通常与具体的商业逻辑紧密相关,该角色里面的工厂方法依据具体的商业逻辑实例化具体的产品并返回,客户端通过该角色并调用该角色的工厂方法,获得具体产品对像,该角色通常都是一个具体 JAVA 类来承担.
3. 抽像产品角色:担任这个角色的类是工厂方法模式所创建的产品的父类,或者他们共同拥有的接口,通常是一个接口或者抽像类.
4. 具体产品角色:抽像工厂模式所创建的任何产品都是这个角色的实例,有一个具体 JAVA 类来承担.
样例代码如下:
跟据上面的模式结构图我们对 "提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类" 进行一个简要的分析:
public class AbstractProductA
{
/**
* @roseuid 59AC05990327
*/
public AbstractProductA()
{
}
}
public class ProductA1 extends AbstractProductA
{
/**
* @roseuid 59AC05990359
*/
public ProductA1()
{
}
}
public class ProductA2 extends AbstractProductA
{
/**
* @roseuid 59AC05990381
*/
public ProductA2()
{
}
}
public class AbstractProductB
{
/**
* @roseuid 59AC059903BA
*/
public AbstractProductB()
{
}
}
public class ProductB1 extends AbstractProductB
{
/**
* @roseuid 59AC059A001F
*/
public ProductB1()
{
}
}
public class ProductB2 extends AbstractProductB
{
/**
* @roseuid 59AC059A0049
*/
public ProductB2()
{
}
}
public abstract class AbstractFactory
{
/**
* @roseuid 59AC05690005
*/
public AbstractFactory()
{
}
/**
* @return AbstractProductA
* @roseuid 59ABFB0103BE
*/
public Abstract AbstractProductA createProductA() ;
/**
* @return AbstractProductB
* @roseuid 59ABFB3B029D
*/
public Abstract AbstractProductB createProductB() ;
}
public class ConcreteFactory1 extends AbstractFactory
{
/**
* @roseuid 59AC057A02FC
*/
public ConcreteFactory1()
{
}
/**
* @return AbstractProductA
* @roseuid 59ABFB9C00C9
*/
public AbstractProductA createProductA()
{
return new ProductA1();
}
/**
* @return AbstractProductB
* @roseuid 59ABFBA30011
*/
public AbstractProductB createProductB()
{
return new ProductB1();
}
}
public class ConcreteFactory2 extends AbstractFactory
{
/**
* @roseuid 59AC057A02C0
*/
public ConcreteFactory2()
{
}
/**
* @return AbstractProductA
* @roseuid 59ABFCC701B9
*/
public AbstractProductA createProductA()
{
return new ProductA2();
}
/**
* @return AbstractProductB
* @roseuid 59ABFCC9001F
*/
public AbstractProductB createProductB()
{
return new ProductB2();
}
}
public class Client
{
/**
* @roseuid 59AC055700AB
*/
public Client()
{
}
public static void main(String[] args){
AbstractFactory theAbstractFactory;
AbstractProductA theAbstractProductA;
AbstractProductB theAbstractProductB;
theAbstractFactory=new ConcreteFactory1();
theAbstractProductA=theAbstractFactory.createProductA();
theAbstractProductB=theAbstractFactory.createProductB();
}
}
1. 相关或相互依赖对像,在这里面 ProductA1 的实例和 ProductB1 的实例就是一组相互关联(如内在的关联关系)或相互依赖(如整体和部分)关系,依据业务逻辑,ProductA1
只能和同一产品等级结构 AbstractProductB 下的 ProductB1 相互关联而无法与 ProductB2 关联在一起.
2. 提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类,这里面的接口,即为结构图中的 AbstractProductA 和 AbstractProductB,客户端只依赖这些产品的接口进行编程,而不依赖于具体实现,即符合依赖倒转原则."无需指定它们具体的类" 即客户端(client)跟本就不知道 ProductA1,ProductA2,ProductB1 和 ProductB2 的存在,客户端只需要调用具体工厂的工厂方法即可返回具体的产品实例.
四,模式样例
我们接着工厂方法模式中的样例进行进一步分析,现在这个生产轮胎的工厂已经不满足只生产轿车轮胎了,他现已经引入了发动机的生产线(EngineLine),车门(DoorLine)等整个车的各种零部件生产线,可以说他现在可以轻松制造一部 Car,但是也并非所有的 Car 都能制造,比如他现只能生产 benz 和 BMW 两种类型的车(这样的工厂也够 NX 了),比如现在一部车只包含车轮胎,车门和发动机(当然肯定不止这么多),那么这个工厂就可以跟据客户的要求生产 BMW 和 benz 车了,如下图:
代码如下:
运行结果如下:
public interface Door {
public void open();
public void close();
}
public class BenzDoor implements Door {
@Override
public void open() {
System.out.println("奔驰车门开");
}
@Override
public void close() {
System.out.println("奔驰车门关");
}
}
public class BmwDoor implements Door {
@Override
public void open() {
System.out.println("宝马车门开");
}
@Override
public void close() {
System.out.println("宝马车门关");
}
}
public interface Tire {
public void getColor();
public void getLife();
public void getWidth();
}
public class BenzTire implements Tire {
@Override
public void getColor() {
System.out.println("benz车color");
}
@Override
public void getLife() {
System.out.println("benz车life");
}
@Override
public void getWidth() {
System.out.println("benz车width");
}
}
public class BmwTire implements Tire {
@Override
public void getColor() {
System.out.println("bmw车color");
}
@Override
public void getLife() {
System.out.println("bmw车life");
}
@Override
public void getWidth() {
System.out.println("bmw车width");
}
}
public interface Engine {
public void start();
public void stop();
}
public class BenzEngine implements Engine {
@Override
public void start() {
System.out.println("benz车start");
}
@Override
public void stop() {
System.out.println("benz车stop");
}
}
public class BmwEngine implements Engine {
@Override
public void start() {
System.out.println("bmw车start");
}
@Override
public void stop() {
System.out.println("bmw车stop");
}
}
public interface PartFactory {
public Door createDoor();
public Tire createTire();
public Engine createEngine();
}
public class BenzPartFactory implements PartFactory {
@Override
public Door createDoor() {
return new BenzDoor();
}
@Override
public Tire createTire() {
return new BenzTire();
}
@Override
public Engine createEngine() {
return new BenzEngine();
}
}
public class BmwPartFactory implements PartFactory {
@Override
public Door createDoor() {
return new BmwDoor();
}
@Override
public Tire createTire() {
return new BmwTire();
}
@Override
public Engine createEngine() {
return new BmwEngine();
}
}
public class Car {
private Door door;
private Engine engine;
private Tire tire;
public Car(PartFactory factory) {
this.door = factory.createDoor();
this.engine = factory.createEngine();
this.tire = factory.createTire();
}
public Door getDoor() {
return door;
}
public Engine getEngine() {
return engine;
}
public Tire getTire() {
return tire;
}
}
public class Client {
public static void main(String[] args) {
PartFactory partFactory=new BenzPartFactory();
Car benzCar=new Car(partFactory);
benzCar.getDoor().open();
benzCar.getEngine().start();
benzCar.getTire().getColor();
}
}
奔驰车门开
benz 车 start
benz 车 color
跟据上面的类图及运行结果可以做如下分析:
BenzDoor,BenzTire 和 BenzEngine 有很强的关联关系,我们可以说一部 benz 车,不可能用 Bmw 的车门,即 BmwDoor.这种很强的关联关系通过 BenzPartFactory 进行了很好的维护.对于客户端来说,如上面的 client 类,如果客户想要一部 benz 车,那么我只需要一个生产 benz 车的工厂即可,这个工厂所有的产品实例,都是 benz 车的部件.从运行结果我们也可以看出.
试想一下,随着这个工厂的发展,他现在也要生产 Audi 的车,这时我们只要增加一个 audi 的车门的类 AudiDoor,AudiTire ,AudiEngine 和 AudiPartFactory 就可以了,其它的类不需要做任何的修改.但客户说,我要在车上装一对翅膀呢,堵车时可以飞,这时我们就要对每个工厂都要增加能返回翅膀的工厂方法,要对每个工厂进行修改,这是不符合开闭原则的.所以说抽象工厂对增加产品等级结构方面是不支持开闭原则的,对于产品族维度(如 audi 车)是支持开闭原则的.
五,模式的约束
对于产生一个相互关联或依赖的产品族适用,且支持在产品族方向的扩展,不适用于产品等级方向的扩展.
六,模式的变体与扩展
1,抽像工厂提供静态工厂方法:抽像工厂可以提供一个静态的工厂方法,通过参数返回具体的工厂实例.
2,抽像工厂与具体工厂合并:如果在产品族方向上确定只有一个产品族,那么抽像工厂就没有必要了,这时只需要一个具体工厂就可以了,我们可以进一步延深,为这个具体工厂提供一个静态方法,该方法返回自已的实例.
七,与其它模式的关系
如果只有一个产品等级结构,那么就是工厂方法模式了,如下图:
如果有多个产品等级结构,那么抽像工厂里面的每一个工厂方法都是 "工厂方法" 模式.
八,模式优缺点
在产口族方向支持开闭原则,在产口等级结构方向不支持开闭原则.
来源: http://www.phperz.com/article/18/0117/353516.html