工厂模式,把new的操作封装起来,屏蔽掉了客户直接接触具体对象的过程,只让客户与基类交互,降低耦合,增强代码的扩展性
简单工厂
把对象的创建放到一个工厂类中,通过参数来创建不同的对象。
这个缺点是每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“不改代码”的原则)(在工厂中为每一个对象的创建都添加一个创建具体对象的方法,每次想要创建对象的时候就调用该方法,不用传一个参数用switch case来选择,这样可以直观点)
简单工厂组成:
1. 工厂类角色:是具体产品类角色直接调用者。(所以实例对象都在一个工厂中创建)
2. 抽象产品角色:接口或抽象类,负责具体产品角色的定义,及与客户端的交互。
3. 具体产品角色:被工厂类创建的对象,也是客户端实际操作对象。
4. 客户端:调用工厂类产生实例,并调用实例的方法进行相应工作。
1. 工厂类角色:是具体产品类角色直接调用者。(所以实例对象都在一个工厂中创建)
2. 抽象产品角色:接口或抽象类,负责具体产品角色的定义,及与客户端的交互。
3. 具体产品角色:被工厂类创建的对象,也是客户端实际操作对象。
4. 客户端:调用工厂类产生实例,并调用实例的方法进行相应工作。
public class AbstractFactory {
public static void main(String[] args) {
VehicleFactory.produceCar();
}
}
abstract class Vehicle{
abstract public void run();
}
class Car extends Vehicle{
@Override
public void run() {
System.out.println("开汽车");
}
}
class Plane extends Vehicle{
@Override
public void run() {
System.out.println("开飞机");
}
}
class VehicleFactory{
static public Vehicle produceCar(){
return new Car();
}
static public Vehicle producePlane(){
return new Plane();
}
}
工厂方法
每种产品由一种工厂来创建,一个工厂保存一个new,完全遵循 “不改代码”的原则(
开放-封闭原则
)。
有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。
在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
工厂方法组成
1. 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3. 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
public class Factory {
public static void main(String[] args) {
new PlaneFactory().produceVehicle().run();
new CarFactory().produceVehicle().run();
}
}
/**
* 工厂接口,(1.抽象工厂类)
* @author chen
*
*/
interface VehicleFactory{
public Vehicle produceVehicle();
}
/**
* 具体工厂(2.具体工厂)
* @author chen
*
*/
class PlaneFactory implements VehicleFactory{
@Override
public Vehicle produceVehicle() {
return new Plane();
}
}
/**
* 具体工厂(2.具体工厂)
* @author chen
*
*/
class CarFactory implements VehicleFactory{
@Override
public Vehicle produceVehicle() {
return new Car();
}
}
/**
* 交通公交接口,抽象交通工具的共同属性(3.抽象产品类)
* @author chen
*
*/
interface Vehicle{
public void run();
}
/**
* 具体交通工具类飞机,实现交通公交接口(4.具体产品类)
* @author chen
*
*/
class Plane implements Vehicle{
@Override
public void run() {
System.out.println("飞机能飞");
}
}
/**
* 具体交通公交类汽车,实现交通公交接口(4.具体产品类)
* @author chen
*
*/
class Car implements Vehicle{
@Override
public void run() {
System.out.println("汽车能跑");
}
}
工厂方法也有局它限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了类爆炸,对于以后的维护来说,简直就是一场灾难.....
什么是产品族
位于不同产品等级结构中,功能相关联的产品组成的家族
产品等级结构
产品等级结构即产品的继承结构,如一个抽象类是汽车,其子类有奔驰,宝马,则抽象汽车与具体品牌的汽车之间构成了一个产品等级结构,抽象汽车是父类,而具体品牌的汽车是其子类
图中的BmwCar和BenzCar就是两个产品树(产品层次结构);而如图所示的BenzSportsCar和BmwSportsCar就是一个产品族。他们都可以放到跑车家族中,因此功能有所关联。同理BmwBussinessCar和BenzSportsCar也是一个产品族。
抽象工厂
意图:
提供一个创建一系列相关或相互依赖的接口,而无需指定它的具体类型。
抽象工厂组成:
● ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
● AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
● ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
抽象工厂和工厂从组成上看基本一致,不同的是顶层的抽象工厂类中声明的是创建一族产品的方法,对应每一类产品。其实相对与工厂方法抽象工厂对生成产品的方法又有更进一步的分类(对产品族的分类),子类工厂对应的是一个品牌树(具体品牌),这样一个工厂就可以生产该品牌的各种产品,但是这样就不符合(开-闭原则)
public class AbstractFactory {
public static void main(String[] args) {
new BmwFactory().produceBusinessCar().makeMoney();
}
}
/**
* 工厂接口,(1.抽象工厂类)
* @author chen
*
*/
interface VehicleFactory{
public BusinessCar produceBusinessCar();
public SportsCar produceSportsCar();
}
/**
* 具体品牌工厂(2.具体工厂)
* @author chen
*
*/
class BmwFactory implements VehicleFactory{
@Override
public BusinessCar produceBusinessCar() {
return new BmwBusinessCar();
}
@Override
public SportsCar produceSportsCar() {
return new BmwSportCar();
}
}
/**
* 具体品牌工厂(2.具体工厂)
* @author chen
*
*/
class BenzFactory implements VehicleFactory{
@Override
public BusinessCar produceBusinessCar() {
return new BenzBusinessCar();
}
@Override
public SportsCar produceSportsCar() {
return new BenzSportsCar();
}
}
/**
* 交通公交接口,抽象交通工具的共同属性(3.抽象产品类)
* @author chen
*
*/
interface BusinessCar{
public void makeMoney();
}
/**
* 交通工具接口,抽象交通工具的共同属性(3.抽象产品类)
* @author chen
*
*/
interface SportsCar{
public void Travel();
}
class BmwSportCar implements SportsCar{
@Override
public void Travel() {
System.out.println("宝马越野车");
}
}
class BmwBusinessCar implements BusinessCar{
@Override
public void makeMoney() {
System.out.println("宝马商务车");
}
}
class BenzSportsCar implements SportsCar{
@Override
public void Travel() {
System.out.println("奔驰越野车");
}
}
class BenzBusinessCar implements BusinessCar{
@Override
public void makeMoney() {
System.out.println("奔驰商务车");
}
}