工厂模式大致分为三种:简单工厂,工厂方法,抽象工厂
我把工程目录贴出来:开发流程时从按照 1、简单工厂,2、、工厂方法,3、抽象工厂
一、简单工厂:
简单工厂模式其实不是一个设计模式,反而比较像一种编程习惯。主要我们定义一个非常简单的类主要负责帮我们生产不同的产品。类图如下:
例子:生产鞋子:NIKE,ADIDAS
package SimpleFactory;
/**
*鞋子的抽象类
*/
public class Shoe {
/**
*名牌
*/
private String brand;
/**
*尺寸
*/
private String size;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
public class Nike extends Shoe {
public Nike(){
this.setBrand("Nike");
}
}
package SimpleFactory;
public class Adidas extends Shoe {
public Adidas(){
this.setBrand("Adidas");
}
}
简单工厂类
package SimpleFactory;
public class ShoeSimpleFactory {
public Shoe getShoe(String brand){
if ("Adidas".equals(brand)){
return new Adidas();
}else if ("Nike".equals(brand)){
return new Nike();
}else{
throw new RuntimeException("不能生产您需要牌子的运动鞋");
}
}
}
package SimpleFactory;
public class SimpleTest {
public static void main(String[] args) {
ShoeSimpleFactory simpleFactory = new ShoeSimpleFactory();
Shoe shoe = simpleFactory.getShoe("Nike");
System.out.println(shoe);
}
}
- 二、工厂方法模式
工厂方法模式是简单工厂模式的一个改进,克服了简单工厂违背开放-封闭原则的缺点,同时保持了封装对象创建过程的优点。工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。也就是将简单工厂抽象成一个接口,让子类的工厂去实现这个接口的过程。
定一个生产鞋子的工厂接口
package factoryMethod;
import SimpleFactory.Shoe;
/**
*工厂方法模式,先定义个生产鞋子的工厂接口,让具体实现给到具体鞋子的工厂
*
*/
public interface Factory {
public Shoe getShoe();
}
具体的工厂
package factoryMethod;
import SimpleFactory.Nike;
import SimpleFactory.Shoe;
public class NikeFactory implements Factory {
@Override
public Shoe getShoe() {
return new Nike();
}
}
package factoryMethod;
public class FactoryMethedTest {
public static void main(String[] args) {
Factory factory1 = new NikeFactory();
System.out.println(factory1.getShoe());
Factory factory2 = new NikeFactory();
System.out.println(factory2.getShoe());
}
}
package factoryMethod;
import SimpleFactory.Adidas;
import SimpleFactory.Shoe;
public class AdidasFactory implements Factory {
@Override
public Shoe getShoe() {
return new Adidas();
}
}
和简单工厂比较, 工厂方法模式将简单工厂中Switch语句的内容放到了子类中去实现,遵循了开放-封闭原则,保持了对象的封装。但是工厂方法模式也存在着不足,工厂方法模式实现时,客户端需要决定实例化哪一个工厂,选择判断的问题还是存在的。工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。要想加功能,本来是改工厂类,现在是修改客户端 。显然这样就不合适了。
三、抽象工厂
抽象工厂模式 定义:提供一个接口(或抽象类),用于创建相关或依赖对象的家族,而不需要明确具体的类
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
示例:脚上用品工厂:(为了配合上面的用例我居然想起了【脚上用品】 )
A套餐工厂的脚上用品的配置 :长筒袜 + nike的鞋子
B套餐工厂的脚上用品的配置 :短筒袜 + Adidas的鞋子
1、先定义袜子的抽象类:
package SimpleFactory;
public class ShortSock extends Sock {
public ShortSock(){
this.setSize("短筒袜子5码");
}
}
package SimpleFactory;
public class LongSock extends Sock {
public LongSock(){
this.setSize("长筒袜子60码");
}
}
package SimpleFactory;
/**
* 袜子的抽象类
*/
public class Sock {
/**
*名牌
*/
private String brand;
/**
*尺寸
*/
private String size;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
2、定一个一个抽象工厂:可以获取鞋子和袜子组合的 脚上用品
package abstractFactory;
import SimpleFactory.Shoe;
import SimpleFactory.Sock;
/**
*脚上用品抽象工厂
*/
public abstract class FootSuppliesAbstractFactory {
/**
*获取鞋子
*/
public abstract Shoe getShoe();
/**
*获取袜子
*/
public abstract Sock getSock();
}
A套餐
package abstractFactory;
import SimpleFactory.*;
/**
* A套餐工厂的脚上用品的配置 :长筒袜 + nike的鞋子
*/
public class FootSuppliesFactoryA extends FootSuppliesAbstractFactory {
@Override
public Shoe getShoe() {
return new Nike();
}
@Override
public Sock getSock() {
return new LongSock();
}
}
B套餐
package abstractFactory;
import SimpleFactory.*;
/**
* B套餐工厂的脚上用品的配置 :短筒袜 + Adidas的鞋子
*/
public class FootSuppliesFactoryB extends FootSuppliesAbstractFactory {
@Override
public Shoe getShoe() {
return new Adidas();
}
@Override
public Sock getSock() {
return new ShortSock();
}
}
测试类:
package abstractFactory;
public class AbstractTest {
public static void main(String[] args) {
//获取A套餐的 脚上装备
FootSuppliesAbstractFactory suppliesAbstractFactoryA = new FootSuppliesFactoryA();
System.out.println(suppliesAbstractFactoryA.getShoe());
System.out.println(suppliesAbstractFactoryA.getSock());
//获取B套餐的 脚上装备
FootSuppliesAbstractFactory suppliesAbstractFactoryB = new FootSuppliesFactoryB();
System.out.println(suppliesAbstractFactoryB.getShoe());
System.out.println(suppliesAbstractFactoryB.getSock());
}
}
抽象工厂
(1)、允许客户使用抽象的接口创建一组相关产品,而不需要知道(或者关心)产出的具体产品是什么,这样客户就可以从具体的产品中解耦出来。
(2)、一个具体工厂可以创建多个产品,与工厂方法模式相比,可以少产生具体工厂的类数量。
(3)、易于交换产品系列,只要更换具体工厂,就可以改变这个产品系列。
2、缺点
(1)、抽象工厂是使用组合的方式把工厂方法集合到一个类中,当新增一个产品家族成员时就要修改抽象工厂类及其下面的具体工厂类,所以它的扩展性比较差。【比如抽象工厂新加获取(护踝绷带)】
(2)、每新增一个产品子类都要创建一个类,当产品子类过多时会产生很多类,导致系统复杂性加大。