为什么有new,还需要工厂呢?
先说答案:灵活控制生产过程, 权限、修饰、日志。
开始比划:比如有个人可以开车、开飞机、开轮船上班,那么对于这些车、飞机、轮船对象可能就需要实现一个接口,当想用车上班,就new Car,想用船上班 就new Ship,如下所示:
public class MainTest {
public static void main(String[] args) {
TravelTools travelTools = new Car();
// 对车的权限、日志
// xxxx
travelTools.goToWork();
TravelTools travelTools1 = new Ship();
// 对船的权限、日志
// xxxx
travelTools1.goToWork();
}
}
interface TravelTools{
void goToWork();
}
class Car implements TravelTools{
@Override
public void goToWork() {
System.out.println("go to work by Car Car Car");
}
}
class Ship implements TravelTools{
@Override
public void goToWork() {
System.out.println("go to work by Ship Ship Ship");
}
}
这种情况下,如果想在船或者某个交通工具生产的过程中,做某些权限设定、或者属性等信息做一些日志等,那么每新建一种类型的交通工具,就得修改代码(改注释的那个地方),以完成新类型交通工具的日志支持。
那么这时候,如果new对象的过程,让一个工厂去做,把日志权限的控制也放到工厂里,那么可以不用修改主要的逻辑代码,以适应灵活扩展。
以下,就做了一个==简单工厂==,这样,每当创建对象的时候,就由对应的工厂对他做权限处理,而不侵入main方法的逻辑业务代码,导致反复修改main方法。
public class FactoryPattern {
// 模拟主要逻辑业务
public static void main(String[] args) {
// 简单工厂
TravelToolsFactory factory = new TravelToolsFactory();
// 用户输入一个 Car 或者 Ship 放到下面的函数中当参数即可 这里省略 直接用Car
TravelTools travelTools = factory.createTravelTool("Car");
travelTools.goToWork();
}
}
// 简单工厂
class TravelToolsFactory{
public TravelTools createTravelTool(String TravelToolType){
if(TravelToolType == "Car")
return createCar();
else if(TravelToolType == "Ship")
return createShip();
return null;
}
private Car createCar(){
// 做日志 权限
// xxx
return new Car();
}
private Ship createShip(){
// 做日志 权限
// xxx
return new Ship();
}
}
但是这样并不是最优的方式,因为很容易发现,当想添加新类型的交通工具时候,就得修改TravelToolsFactory
这个类的代码,根据开闭原则,这样当然不是最优,那么,如果把工厂的构建,也交给扩展,相当把工厂作为一个可插拔的模块,就会更加灵活,以如下方式:每当想更换交通工具,只需要编写新的工厂,并改下面第4行的代码,new一个新的工厂,这种方式,就是==工厂模式==。
public class MainTest {
public static void main(String[] args) {
// 工厂模式
AbstractTravelToolsFactory absFactory = new ShipTravelToolsFactory(); // 如果想更换交通工具,只需要编写新的工厂,并改这里创建工厂
TravelTools travelTools = absFactory.createTravelTools();
travelTools.goToWork();
}
}
// 工厂模式 -- 交通工具工厂 -- 这样的好处是若想增加火箭交通工具, 只需要再写火箭的创建工厂,并在里面做相应权限控制即可
abstract class AbstractTravelToolsFactory{
abstract TravelTools createTravelTools();
}
// 交通工具
interface TravelTools{
void goToWork();
}
// 交通工具:车
class Car implements TravelTools{
@Override
public void goToWork() {
System.out.println("go to work by Car Car Car");
}
}
// 车的工厂
class CarTravelToolsFactory extends AbstractTravelToolsFactory{
@Override
TravelTools createTravelTools() {
// 做业务权限控制
Car car = new Car();
return car;
}
}
// 交通工具:船
class Ship implements TravelTools{
@Override
public void goToWork() {
System.out.println("go to work by Ship Ship Ship");
}
}
// 船的工厂
class ShipTravelToolsFactory extends AbstractTravelToolsFactory{
@Override
TravelTools createTravelTools() {
// 做业务权限控制
Ship ship = new Ship();
return ship;
}
}
所以,工厂模式的主要是目的为了在某个对象的创建过程中,如果想要进行某些权限控制时,可以用该方法,以减少代码的修改,满足开闭原则。
那么通过1的工厂模式,我们已经相对做的ok了,但是今天来了新需求,说这人上班不但要坐交通工具,还要玩手机或者看报纸, 同时还要喝咖啡或者牛奶!三个一起开搞,相当于对于这人来说,要给他配置一套东西(产品族),出行的,看的,喝的。
那么这时候,我们就需要在工厂模式的基础上,再进行更高层次的抽象,搞一个抽象的工厂,用于生产一套(族)抽象的东西,而具体的工厂继承这个抽象工厂并实现相应的方法,以生成一系列的真实的东西。
先屡屡实体,这里面涉及到:交通工具TraveTools(有Car、Ship);看的Reading(有NewsParper、Phone);喝的Drinking(有Milk、Coffee)
那么抽象工厂AbstractFactory 就需要生产三个抽象东西:交通工具TraveTools、看的Reading、喝的Drinking
具体工厂就得自由搭配实际的东西,生产实际的3种东西。如我这里的:
套餐1工厂 MenuOneFactory 生产:Car [ 交通工具 ]、NewsParper [ 看的 ]、Milk [ 喝的 ]
套餐2工厂 MenuTwoFactory 生产:Ship[ 交通工具 ]、Phone[ 看的 ]、Coffee [ 喝的 ]
具体的整个结构如下:看左边抽象工厂的那几个抽象方法,像不像插座? 看右边具体的工厂实现的3个方法像不像插头,刚好通过3个接口联系起来,每当想要添加新的套餐的时候,新建一个套餐工厂,插上去就好了!是不是可扩展性好了许多!
具体的代码如下:
public class MainTest {
public static void main(String[] args) {
// 这样,如果想重新构建一个套餐(家族), 重新添加一个套餐构建工厂, new一个新的套餐工厂,即可全部修改
// AbstractFactory factory = new MenuOneFactory();
MenuTwoFactory factory = new MenuTwoFactory(); // 套餐2工厂
// 就算需要新的套餐,以下部分的代码也不需要改动
TravelTools travelTools = factory.createTravelTools();
travelTools.goToWork();
Reading reading = factory.createReading();
reading.read();
Drinking drinking = factory.createDrinking();
drinking.drink();
}
}
// 抽象工厂用于生产一些列抽象东西
abstract class AbstractFactory{
abstract TravelTools createTravelTools();
abstract Reading createReading();
abstract Drinking createDrinking();
}
// 套餐1 车、报纸、牛奶 ,具体的工厂,生产一些列具体东西
class MenuOneFactory extends AbstractFactory {
@Override
TravelTools createTravelTools() {
return new Car();
}
@Override
Reading createReading() {
return new NewsParper();
}
@Override
Drinking createDrinking() {
return new Milk();
}
}
//套餐2 船、 手机、 咖啡 ,具体的工厂,生产一些列具体东西
class MenuTwoFactory extends AbstractFactory {
@Override
TravelTools createTravelTools() {
return new Ship();
}
@Override
Reading createReading() {
return new Phone();
}
@Override
Drinking createDrinking() {
return new Coffee();
}
}
// 出行的
interface TravelTools{
void goToWork();
}
// 看的
interface Reading {
void read();
}
// 喝的
interface Drinking{
void drink();
}
class Car implements TravelTools { xxx }
class Ship implements TravelTools { xxx }
class NewsParper implements Reading { xxx }
class Phone implements Reading { xxx }
class Coffee implements Drinking { xxx }
class Milk implements Drinking { xxx }