工厂模式通常分为简单工厂、工厂方法和抽象工厂三种,
1、简单工厂模式code
建立一个工厂类,根据传入的参数来决定建立哪一个汽车类对象
//汽车接口
public interface Car {
void getCar();
}
//宝马汽车类
public class BMWCar implements Car {
@Override
public void getCar() {
System.out.println("这是宝马车");
}
}
//奔驰汽车类
public class BenzCar implements Car {
@Override
public void getCar() {
System.out.println("这是奔驰车");
}
}
//工厂类,用于决定建立哪个具体的汽车类
public class DefaultFactory {
public Car produce(String name){
if(name.equals("benz")){
return new BenzCar();
}else if(name.equals("bmw")){
return new BMWCar();
}
return null;
}
}
public class FTest {
public static void main(String[] args) {
DefaultFactory factory = new DefaultFactory();
Car car = factory.produce("bmw");
car.getCar(); //这是宝马车
Car benz = factory.produce("benz");
benz.getCar(); //这是奔驰车
}
}
能够看到,在具体的工厂类DefaultFactory中,咱们根据传入的name来决定建立哪个汽车类。当须要建立宝马时,传入bmw,当须要建立奔驰时传入benz。思考一下,若是我须要建立一个大众汽车呢。是否是须要建立一个大众汽车类实现Car接口,还须要修改工厂类的produce方法,新增一个大众的分支。 再回忆一下,以前讲过的软件六大设计原则之一开闭原则。很明显,这违背了开闭原则(对修改是关闭的)。blog
因而,有了下边的工厂方法,能够保证遵循开闭原则。接口
2、工厂方法模式get
工厂方法,相比于简单工厂,多了一个角色——工厂接口,负责定义生产汽车的公共接口,而后每一个工厂实现类都去实现这个接口。产品
//工厂接口
public interface IFactory {
Car produce();
}
//宝马生产工厂
public class BMWFactory implements IFactory{
@Override
public Car produce() {
return new BMWCar();
}
}
//奔驰生产工厂
public class BenzFactory implements IFactory {
@Override
public Car produce() {
return new BenzCar();
}
}
public class FacTest {
public static void main(String[] args) {
BMWFactory bmwFactory = new BMWFactory();
bmwFactory.produce().getCar(); //这是宝马车
BenzFactory benzFactory = new BenzFactory();
benzFactory.produce().getCar(); //这是奔驰车
}
}
能够看到,我把以前的一个工厂,拆分为两个工厂。当具体须要哪一个汽车的时候,就去实例化它对应的工厂。这样,当再须要大众车的时候,我只须要添加一个大众车的类和大众车对应的工厂实现类去实现IFactory接口就能够了。不须要修改原来的代码,这就符合开闭原则了。class
3、 抽象工厂模式扩展
咱们就把高配制造商或者低配制造商称为一个产品族。而其中的低配宝马和低配奔驰属于同一个产品等级,高配宝马和高配奔驰属于同一个产品等级。
画一张图来理解一下它们的概念,横向是三个产品族,纵向是两个产品等级。
代码以下:
// 路由
public interface IRouterProduct {
void start();
void setwife();
void shutdown();
}
//手机
public interface PhoneProduct {
void start();
void callup();
void shutdown();
}
//华为路由
public class HuaweiIRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("Huawei路由开启");
}
@Override
public void setwife() {
System.out.println("Huawei路由开启");
}
@Override
public void shutdown() {
System.out.println("Huawei路由开启");
}
}
// 小米路由
public class XiaomiIRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("Xiaomi路由开启");
}
@Override
public void setwife() {
System.out.println(" Xiaomi路由设置");
}
@Override
public void shutdown() {
System.out.println(" Xiaomi路由关机");
}
}
// 华为手机
public class HuaweiPhone implements PhoneProduct {
@Override
public void start() {
System.out.println(" Huawei开机");
}
@Override
public void callup() {
System.out.println("Huawei打电话");
}
@Override
public void shutdown() {
System.out.println(" Huawei关机");
}
}
// 小米手机
public class XiaomiPhone implements PhoneProduct
{
@Override
public void start() {
System.out.println("XiaomiPhone开机");
}
@Override
public void callup() {
System.out.println("XiaomiPhone打电话");
}
@Override
public void shutdown() {
System.out.println("XiaomiPhone关机");
}
}
// 路由手机产品工厂
public interface IProductFactory {
PhoneProduct productPhoneProduct();
IRouterProduct proRouterProduct();
}
// 小米工厂
public class XiaomiFactory implements IProductFactory {
@Override
public PhoneProduct productPhoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct proRouterProduct() {
return new XiaomiIRouter();
}
}
// 华为工厂
public class HuaweiFactory implements IProductFactory {
@Override
public PhoneProduct productPhoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct proRouterProduct() {
return new HuaweiIRouter();
}
}
// 测试类
public class Test01 {
public static void main(String[] args) {
XiaomiFactory xiaomiFactory = new XiaomiFactory() ;
PhoneProduct xiaomiPhone = xiaomiFactory.productPhoneProduct();
xiaomiPhone.callup();
IRouterProduct xiaoRouter = xiaomiFactory.proRouterProduct();
xiaoRouter.start();
}
}
总结:
- 简单工厂顾明思议,实现比较简单,只须要传入一个特定参数便可,在实际项目中用的比较多,缺点就是违背了开闭原则。
- 工厂方法和抽象工厂,遵照开闭原则,解耦了类关系。可是,扩展比较复杂,须要增长一系列的类 一种car 需要一个carFactory。
- 须要注意,工厂方法和抽象工厂的区别就在于,抽象工厂关注于某一个产品族,当产品对象之间是有关联关系的一个产品族时用这种方式,而工厂方法没有产品族的概念(只能单一增加产品比如苹果手机、华为手机、小米手机等)。抽象工厂如果增加一个产品 比如笔记本那么所有的工厂 方法都要重写,所以不支持产品的拓展,支持产品族的新增,比如增加opper 手机