目录
简单工厂
定义:
提供一个创建对象实例的功能,而无需关心具体的实现。被创建的实例对象可以是接口,抽象类,也可以是具体的类
角色:
工厂(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文本等。我们需要根据系统来切换不同的产品族,达到使用不同系统的控件)。
总结:
工厂模式帮我们统一生产对象,我们不需要知道对象具体生成逻辑。使得对象的创建与使用解耦。