目录
简单工厂
定义:
提供一个创建对象实例的功能,而无需关心具体的实现。被创建的实例对象可以是接口,抽象类,也可以是具体的类
角色:
工厂(creator)角色
简单工厂的核心,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。
抽象(Product)产品角色
简单工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。
具体(ConcreteProduct)产品角色
是简单工厂创建的目标,所创建的对象都是具体类的实例。
实现:
以person为例,具体产品为man,women,工厂角色为personFactory
package com.lxlyq.factoryPattern.simpleFactory;
/**
* 抽象产品
*/
public abstract class Person {
private String name;
private String age;
public abstract void seeName();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
package com.lxlyq.factoryPattern.simpleFactory;
public class Man extends Person {
public Man() {}
public Man(String name){
this.setName(name);
}
@Override
public void seeName() {
System.out.println(this.getName());
}
}
package com.lxlyq.factoryPattern.simpleFactory;
public class Women extends Person {
public Women(){}
public Women(String name) {
this.setName(name);
}
@Override
public void seeName() {
System.out.println(this.getName());
}
}
package com.lxlyq.factoryPattern.simpleFactory;
/**
* 提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类
*/
public class PersonFactory {
public static final int MAN = 1;
public static final int WOMEN = 2;
public Person createMan(int type, String name) {
switch (type) {
case MAN:
return new Man(name);
case WOMEN:
return new Women(name);
default:
throw new RuntimeException("don't has type");
}
}
}
客服端调用
package com.lxlyq.factoryPattern.simpleFactory;
public class SimpleFactoryDemo {
public static void main(String[] args) {
Person man = new PersonFactory().createMan(PersonFactory.MAN, "women");
man.seeName();
}
}
优缺点
优点:
客户端只需创建一个工厂,而不用担心对象具体怎么实现。
缺点:
每次增加一个产品时,都需要更改工厂类,增加case或elseif判断创建新的产品对象,使得维护变得困难。
使用场景
- 工厂类负责创建的对象比较少;
- 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
- 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
工厂方法
定义:
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
角色:
抽象工厂(creator)角色
工厂方法的核心,与应用程序无关。提供一公共接口创建抽象产品方法,具体的实现由具体工厂实现。
具体工厂(ConcreateCreator)角色
对应简单工厂的工厂类,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。但是不同的是,一个具体工厂只创建一个产品。所有的具体工厂都必须实现抽象工厂类。
抽象产品(Product)角色
具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。
具体产品(ConcreteProduct)角色
这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。
实现:
以汽车工厂为例,有宝马工厂,有奔驰工厂,汽车抽象类,奔驰,宝马,具体如下
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 抽象产品
*/
public abstract class Car {
private String name;
public abstract void driver();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 宝马
*/
public class BaoMaCar extends Car {
{
this.setName("baoMaCar");
}
@Override
public void driver() {
System.out.println(this.getName());
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 奔驰
*/
public class BenCiCar extends Car {
{
this.setName("benCiCar");
}
@Override
public void driver() {
System.out.println(this.getName());
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
*/
public abstract class CarFactory {
private String carName;
public abstract Car createCar();
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 奔驰工厂
*/
public class BenCiFactory extends CarFactory {
{
this.setCarName("benCi");
}
@Override
public Car createCar() {
return new BenCiCar();
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 宝马工厂
*/
public class BaoMaFactory extends CarFactory {
{
this.setCarName("baoMa");
}
@Override
public Car createCar() {
return new BaoMaCar();
}
}
package com.lxlyq.factoryPattern.factoryMethod;
/**
* 测试
*/
public class FactoryMethodDemo {
public static void main(String[] args) {
Car baoMaCar = new BaoMaFactory().createCar();
baoMaCar.driver();
Car benCiCar = new BenCiFactory().createCar();
benCiCar.driver();
}
}
优缺点
优点:
客户端不需要知道具体的产品,只有知道产品对应的工厂类。
增加一个产品只用增加一个具体工厂实现抽象工厂,增加一个具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。
缺点:
产品与工厂类都是成对出现,这使得系统中的类越来越多。
使用场景
- 对于某个产品,调用者清楚需要实例化那个具体工厂来生产需要使用的实例;
- 调用方只是需要一种产品,而不想知道也不需要知道它由那个工厂生产。由生产者根据系统环境或其他条件创建一个工厂返回给调用方,调用方通过工厂创建对象,这个决策对于调用方是透明的;
抽象工厂
定义:
抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。抽象工厂模式也称Kit模式,它属于类创建型模式。
角色:
抽象工厂(creator)角色
抽象工厂的核心,它包含多个创建产品的方法 ,可以创建多个不同等级的产品。所有需要创建的不同等级的产品都需要在工厂中定义一个方法。
具体工厂(ConcreateCreator)角色
实现了抽象工厂的抽象方法,完成了具体产品的创建。具体工厂创建的产品应该至少2个。
抽象产品(Product)角色
具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。
具体产品(ConcreteProduct)角色
这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。
实现:
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 抽象产品
*/
public interface Shape {
void draw();
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 产品种类
*/
public abstract class Circle implements Shape {
@Override
public abstract void draw();
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 产品种类
*/
public abstract class Rectangle implements Shape {
@Override
public abstract void draw();
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 不同等级
*/
public class BlueCircle extends Circle {
@Override
public void draw() {
System.out.println("blueCircle");
}
}
package com.lxlyq.factoryPattern.abstractFactory;
public class BlueRectangle extends Rectangle {
@Override
public void draw() {
System.out.println("blueRectangle");
}
}
package com.lxlyq.factoryPattern.abstractFactory;
public class RedCircle extends Circle {
@Override
public void draw() {
System.out.println("draw redCircle");
}
}
package com.lxlyq.factoryPattern.abstractFactory;
public class RedRectangle extends Rectangle {
@Override
public void draw() {
System.out.println("draw RedRectangle");
}
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
* 抽象工厂模式也称Kit模式,它属于类创建型模式。
*/
public interface ShapeFactory {
Shape getCircle();
Shape getRectangle();
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 产品族1工厂
*/
public class BlueShapeFactory implements ShapeFactory {
@Override
public Shape getCircle() {
return new BlueCircle();
}
@Override
public Shape getRectangle() {
return new BlueRectangle();
}
}
package com.lxlyq.factoryPattern.abstractFactory;
/**
* 产品族2工厂
*/
public class RedShapeFactory implements ShapeFactory{
@Override
public Shape getCircle() {
return new RedCircle();
}
@Override
public Shape getRectangle() {
return new RedRectangle();
}
}
package com.lxlyq.factoryPattern.abstractFactory;
public class AbstractFactoryDemo {
public static void main(String[] args) {
ShapeFactory blueShapeFactory = new BlueShapeFactory();
Shape circle = blueShapeFactory.getCircle();
Shape rectangle = blueShapeFactory.getRectangle();
circle.draw();
rectangle.draw();
// 切换工厂
ShapeFactory redShapeFactory = new RedShapeFactory();
circle = redShapeFactory.getCircle();
rectangle = redShapeFactory.getRectangle();
circle.draw();
rectangle.draw();
}
}
从demo中知道,我们切管产品族只需要切换工厂即可。
优缺点
优点:
它分离了具体的类;
它使得易于交换产品系列;
它有利于产品的一致性;
增加一个产品产品族只用增加一个具体工厂实现抽象工厂,增加具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。
缺点:
当新增一个产品种类时,(新增一个多边形),那么需要在抽象工厂中增加一个创建多边形的方法,从而之前写的所有具体工厂都需要变动,不符合开闭原则(难以支持新种类的产品)。
使用场景
- 抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件。
- 当我们需要多个产品族,而每次只单独使用其中一个产品族时(如操作系统中的控件,产品族分为Linux,windows,有linux按钮,windows按钮,linux文本,windows文本等。我们需要根据系统来切换不同的产品族,达到使用不同系统的控件)。
总结:
工厂模式帮我们统一生产对象,我们不需要知道对象具体生成逻辑。使得对象的创建与使用解耦。