您的位置:首页 > 其它

【设计模式学习笔记】 之 抽象工厂模式

2018-02-15 15:13 225 查看

简介:

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

举例:每个汽车4s店和某个品牌工厂之间的关系,每个汽车4s店只会卖同一品牌的汽车,但是如果这一品牌汽车销量不好,效益不佳,那么4s店可以更换进货的工厂,从而更换其售卖的品牌。

分析:每个品牌的汽车都有一个品牌工厂,这些工厂都有一个生产汽车的方法,4s店中应持有工厂的引用,所以这些汽车工厂都应该实现一个汽车工厂接口,这个4s店中持有汽车工厂的接口,以便更换汽车工厂改变品牌。

实现:

汽车工厂是用来生产汽车的,所以首先应该有一个汽车接口,所有汽车都有一个run方法

package com.mi.abstractfactory;

public interface Car {

void run();
}

实现这个接口创建一款汽车

package com.mi.abstractfactory;

/**
* 沃尔沃汽车
*/
public class VolvoCar implements Car{

@Override
public void run() {
System.out.println("沃尔沃:别赶路,去感受路!");
}

}

有了汽车类了,这样就可以使用工厂来批量生产了,创建一个汽车工厂接口,其中包含一个生产汽车的方法

package com.mi.abstractfactory;

/**
* 汽车工厂接口
* @author hellxz
*/
public interface AbstractCarFactory {

//接口中所有的没有使用权限修饰符的方法,都是public static final的
Car getCar();
}

2.实现一个品牌汽车工厂

package com.mi.abstractfactory;
/**
* 沃尔沃汽车工厂
*/
public class VolvoCarFactory implements AbstractCarFactory {

@Override
public VolvoCar getCar() {
return new VolvoCar();
}

}

3.创建一个汽车4s店,这个店铺需要有一个卖车的方法saleCar(),并持有一个工厂的引用

package com.mi.abstractfactory;

public class SSSS {

/**
* 实现抽象工厂对象的 注入有两种方式,一种是set设值注入,构造方法,都持有接口的引用
*/
//持有引用,可以根据多态性,传入该接口的实现类型,从而实现不同的效果
private AbstractCarFactory carFactory;

public Car saleCar() {
return carFactory.getCar(); //抽象工厂获取方式得到car对象,可以是car的子类,多态
}

public void setCarFactory(AbstractCarFactory carFactory) {
this.carFactory = carFactory;
}

}

为了能看出来更换工厂的效果,同理创建一个Benz汽车的类和工厂

package com.mi.abstractfactory;

/**
* 奔驰汽车
* @author hellxz
*/
public class BenzCar implements Car {

@Override
public void run() {
System.out.println("奔驰:随时准备好上路疾驶!");
}

}
package com.mi.abstractfactory;

/**
* 奔驰汽车工厂
* @author hellxz
*/
public class BenzCarFactory implements AbstractCarFactory {

@Override
public BenzCar getCar() {
return new BenzCar();
}

// 也可以这样写,返回父类的引用,因为多态(动态绑定),在运行的时候会确定该类型 的具体类型
/*    public Car getCar() {
*        return new BenzCar();
*    }
*/

}

测试类

package com.mi.abstractfactory;

/**
* @author hellxz
*/
public class Test {

public static void main(String[] args) {
SSSS ssss = new SSSS();
//        ssss.setCarFactory(new BenzCarFactory()); //奔驰的工厂
ssss.setCarFactory(new VolvoCarFactory()); //沃尔沃的工厂
Car car = ssss.saleCar();
car.run();
}
}

输出:

沃尔沃:别赶路,去感受路!

测试更换工厂,打开注释行,注释掉沃尔沃的工厂行

输出:

奔驰:随时准备好上路疾驶!

 

总结:

主要解决:主要解决接口选择的问题。

何时使用:一个系统中有多个系列可选择的情况,每次只能选择其中一系列

优点:

  1. 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  2. 降低耦合

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 接口 里加代码,又要在具体的里面加代码。

使用场景: 1、更换一整套的产品  2、生成不同操作系统的程序。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: