工厂模式
What
工厂模式(Factory Pattern) : 属于创建型模式,类的职责大概有三类:自身职责,创建职责,使用职责,当一个类A需要创建类B同时需要使用类B,那么他们的耦合度太高,这个时候可以使用工厂模式,使创建职责与使用职责分离,降低类A与类B的耦合度。
同时,如果一个类的创建太过复制麻烦繁琐,如果多出地方需要用到该类,那么势必增加维护的代价,减少代码可读性等等问题,使用工厂模式封装起来,降低维护成本。
主要分为:
- 简单工厂模式(静态工厂)
- 工厂模式
- 抽象工厂模式
Why
- 解耦;
- 封装创建过程;
- 降低维护成本;
How
示例:简单工厂模式/静态工厂
//测试类
public class Test {
public static void main(String []args) {
//
Animal cat = AnimalFactory.getInstance("cat");
cat.eat();
//
Animal sheep = AnimalFactory.getInstance("sheep");
sheep.eat();
//
Animal earthworm = AnimalFactory.getInstance("earthworm");
earthworm.eat();
}
}
//动物工厂
class AnimalFactory{
public static Animal getInstance(String animal) {
switch ( animal ) {
case "cat" : return new Cat();
case "sheep" : return new Sheep();
case "earthworm" : return new Earthworm();
default : return null;
}
}
}
//动物抽象
interface Animal{
void eat();
}
//猫吃鱼
class Cat implements Animal{
@Override
public void eat(){
System.out.println("Cat eat [Fish]");
}
}
//羊吃草
class Sheep implements Animal{
@Override
public void eat(){
System.out.println("Sheep eat [Grass]");
}
}
//蚯蚓吃土
class Earthworm implements Animal{
@Override
public void eat(){
System.out.println("Earthworm eat [Terra]");
}
}
特点可以看到动物工程类AnimalFactory
的 getInstance
方法是静态的;
优点很明显:代码结构简单易维护;
缺点也很明显:如果再增加一个动物类Dog,那么就需要修改getInstance
方法。
示例:工厂方法
//测试类
public class Test {
public static void main(String []args) {
//
IFactory catFactory = new CatFactory();
Animal cat = catFactory.getInstance();
cat.eat();
//
IFactory sheepFactory = new SheepFactory();
Animal sheep = sheepFactory.getInstance();
sheep.eat();
//
IFactory earthwormFactory = new EarthwormFactory();
Animal earthworm = earthwormFactory.getInstance();
earthworm.eat();
}
}
//抽象工厂
interface IFactory{
public Animal getInstance();
}
class CatFactory implements IFactory{
@Override
public Animal getInstance() {
return new Cat();
}
}
class SheepFactory implements IFactory{
@Override
public Animal getInstance() {
return new Sheep();
}
}
class EarthwormFactory implements IFactory{
@Override
public Animal getInstance() {
return new Earthworm();
}
}
//动物抽象
interface Animal{
void eat();
}
//猫吃鱼
class Cat implements Animal{
@Override
public void eat(){
System.out.println("Cat eat [Fish]");
}
}
//羊吃草
class Sheep implements Animal{
@Override
public void eat(){
System.out.println("Sheep eat [Grass]");
}
}
//蚯蚓吃土
class Earthworm implements Animal{
@Override
public void eat(){
System.out.println("Earthworm eat [Terra]");
}
}
特点:可以看工厂被抽象出来IFactory
,与静态工厂对比,单个工厂被分为多个工厂实体类CatFactory/SheepFactory/EarthwormFactory
;
优点:如果增加一个动物Dog,那么只需要增加一个动物实体类Dog,与一个DogFactory工厂,符合开闭原则;
缺点:系统类成对增加,一个具体工厂类只能创建一种具体产品。
示例:抽象工厂
//测试类
public class Test {
public static void main(String []args) {
//
IFactory catFactory = new CatFactory();
Animal cat = catFactory.getAnimalInstance();
AnimalFood catFood = catFactory.getAnimalFoodInstance();
catFood.product();
cat.eat();
//
IFactory sheepFactory = new SheepFactory();
Animal sheep = sheepFactory.getAnimalInstance();
AnimalFood sheepFood = sheepFactory.getAnimalFoodInstance();
sheepFood.product();
sheep.eat();
//
IFactory earthwormFactory = new EarthwormFactory();
Animal earthworm = earthwormFactory.getAnimalInstance();
AnimalFood earthwormFood = earthwormFactory.getAnimalFoodInstance();
earthwormFood.product();
earthworm.eat();
}
}
//抽象工厂
interface IFactory{
Animal getAnimalInstance();
AnimalFood getAnimalFoodInstance();
}
//猫类相关工厂
class CatFactory implements IFactory {
@Override
public Animal getAnimalInstance(){
return new Cat();
}
@Override
public AnimalFood getAnimalFoodInstance(){
return new Fish();
}
}
//羊类相关工厂
class SheepFactory implements IFactory {
@Override
public Animal getAnimalInstance(){
return new Sheep();
}
@Override
public AnimalFood getAnimalFoodInstance(){
return new Grass();
}
}
//蚯蚓类相关工厂
class EarthwormFactory implements IFactory {
@Override
public Animal getAnimalInstance(){
return new Earthworm();
}
@Override
public AnimalFood getAnimalFoodInstance(){
return new Terra();
}
}
//动物抽象
interface Animal{
void eat();
}
//猫吃鱼
class Cat implements Animal{
@Override
public void eat(){
System.out.println("Cat eat [Fish]");
}
}
//羊吃草
class Sheep implements Animal{
@Override
public void eat(){
System.out.println("Sheep eat [Grass]");
}
}
//蚯蚓吃土
class Earthworm implements Animal{
@Override
public void eat(){
System.out.println("Earthworm eat [Terra]");
}
}
//动物食品
interface AnimalFood{
void product();
}
//鱼
class Fish implements AnimalFood{
@Override
public void product(){
System.out.println("Food : [Fish]");
}
}
//草
class Grass implements AnimalFood{
@Override
public void product(){
System.out.println("Food : [Grass]");
}
}
//土
class Terra implements AnimalFood{
@Override
public void product(){
System.out.println("Food : [Terra]");
}
}
个人理解:抽象工厂可以看成是工厂模式的拓展。
三种工厂各有优缺点,看实际业务开发情况。
When & Where
用到的地方:
- Spring的
getBean
- JDBC
- 等等
结束语:优秀是一种习惯。