工厂模式


目录

  • 工厂模式
  • 简单工厂模式
  • 1. 角色说明
  • 2. 实例演示
  • 3.使用
  • 4.总结
  • 工厂方法模式
  • 1.角色说明
  • 2.实例演示
  • 3.使用
  • 4.总结
  • 抽象工厂模式
  • 1.角色说明
  • 2.实例演示
  • 3.使用
  • 4.总结


简单工厂模式

定义一个用于创建对象的接口,让子类决定实例化哪个类(也可以叫做静态工厂模式)

1. 角色说明

  • 产品:需要创建的复杂对象(一般为interface/abstract形式)。
  • 具体产品:产品的具体实现。
  • 工厂类:根据入参返回产品的具体实现。

2. 实例演示

产品

public abstract class Product{
		public abstract void a();
		public abstract void b();
	}

产品实现类

/**
 * 具体产品A
 */
public class ProductA extends Product{
	
	@Override
	public void a(){
		System.out.println("PA a");
	}
	
	@Override
	public void b(){
		System.out.println("PA b");
	}
}

/**
 * 具体产品B
 */
public class ProductB extends Product{
	
	@Override
	public void a(){
		System.out.println("PB a");
	}
	
	@Override
	public void b(){
		System.out.println("PB b");
	}
}

工厂类

public class Factroy{
	public static Product create(String type){
		Product p = null;
		switch(type){
			case "A":
				p = new ProductA();break;
			case "B":
				p = new ProductB();break;
			default :
		}
		return p;
	}
}

3.使用

我们这里使用工厂类的create方法,根据传入的参数的不同,生成不同的产品。

public class test{
    public void test(){
	    Factory.create("A").a();
	    Factory.create("B").b();
    }
}

Output

PA a
PB b

4.总结

  • 我们生成复杂对象时,当我们确定只使用一个工厂类的时候,我们可以使用简单工厂模式。
  • 简单工厂模式可以把创建实例的过程与使用实例分开,降低代码的耦合度,尤其时当实现类需要大量设置参数的时候(也就是我们new一个对象之后要set很多参数的实例),使用这个实例时我们就不用关心这个对象是如何创建的了
  • 像第一条所说,我们只能有一个工厂类,而且我们使用的静态创建方法,不能被继承和重写,这就导致我们如果要添加新的产品必须修改工厂类逻辑,是得工厂类过于复杂,一旦工厂类出错,则会影响整个系统,这违背了开闭原则。(这也就是简单工厂的弊端)

工厂方法模式

定义一个接口用来创建对象,让他的子类去决定实例化哪个类。

1.角色说明

  • 抽象产品:定义对象的公共接口用来创建复杂对象
  • 具体产品:实现接口
  • 抽象工厂:包含一个方法用来返回抽象产品的对象
  • 具体工厂:返回具体产品。

2.实例演示

定义抽象产品

public abstract class Product{
	public abstract void deal();
}

具体产品实现

public class ProductA extends Product {
        @Override
        public void deal() {
            System.out.println("product A");
        }
    }

    public class ProductB extends Product {
        @Override
        public void deal() {
            System.out.println("product B");
        }
    }

抽象工厂

public abstract class Factory {
        public abstract Product create();
    }

具体工厂实现

public class FactoryA extends Factory {
        @Override
        public Product create() {
            return new ProductA();//创建ProductA
        }
    }
    
    public class FactoryB extends Factory {
        @Override
        public Product create() {
            return new ProductB();//创建ProductB
        }
    }

3.使用

public class test{
	public void test() {
        Factory factoryA = new FactoryA();
        Product productA = factoryA.create();
        productA.deal();
        
        Factory factoryB = new FactoryB();
        Product productB = factoryB.create();
        productB.deal();
    }
}

Output

product A
product B

4.总结

  • 工厂方法模式符合开闭原则,符合单一职责原则,每个工厂都只负责对应的产品
  • 由于一个工厂只能创建一个产品没所以当新增产品时,就需要新增相应的工厂类,导致系统负责度和性能开销,引入抽象类也会导致类结构的复杂化

抽象工厂模式

提供一个接口去创建一组相关或者相互依赖的对象,不用去制定他们的具体类。

1.角色说明

  • 抽象产品:提供一个公共接口
  • 具体产品:一个具体的产品,实现抽象产品接口。
  • 抽象工厂:提供一个抽象类去定义一些创建产品的方法。
  • 具体工厂:实现抽象工厂中定义的创建产品的方法,每一个具体工厂对应生产一种具体产品。

2.实例演示

抽象公共接口

public abstract class Guitar{
	public abstract void getGuitar();
}
public abstract class Bass{
	public abstract void getBass();
}
public abstract class Drum{
	public abstract void getDrum();
}

具体产品实现

public class ESP extends Guitar{
	 @Override
	 public void getGuitar() {
            System.out.println("Guitar:ESP");
     }
}
public class Fender extends Guitar{
	@Override
	public void getGuitar() {
            System.out.println("Guitar:Fender");
	}
}
public class ESP extends Bass{
	 @Override
	 public void getBass() {
            System.out.println("Bass:ESP");
     }
}
public class Fender extends Bass{
	@Override
	public void getBass() {
            System.out.println("Bass:Fender");
	}
}
public class Roland extends Drum{
	 @Override
	 public void getDrum() {
            System.out.println("Drum:Roland");
     }
}
public class Gretsch extends Drum{
	@Override
	public void getDrum() {
            System.out.println("Drum:Gretsch");
	}
}

抽象工厂

public abstract class BankFactory{
	public abstract Guitar createGuitar();
	public abstract Bass createBass();
	public abstract Drum createDrum();
}

具体工厂类

public class PopBankFactory extends BankFactory{
	@Override
    public Guitar createGuitar() {
        return new Fender();
    }
    
    @Override
    public Bass createBass(){
    	return new Fender();
    }
    
    @Override
	public Drum createDrum(){
		return new Gretsch();
	}
}

public class RockBankFactory extends BankFactory{
	@Override
    public Guitar createGuitar() {
        return new ESP();
    }
    
    @Override
    public Bass createBass(){
    	return new ESP();
    }
    
    @Override
	public Drum createDrum(){
		return new Roland();
	}
}

3.使用

这里我们就可以根据不同的需要生产特定的组合产品了。

public class test{ 
    public void test(){
	    System.out.println("--------------------组建一支摇滚乐队-----------------------");
	    RockBankFactory rockBand = new RockBankFactory();
	    rockBand.createGuitar().getGuitar();
	    rockBand.createBass().getBass();
	    rockBand.createDrum().getDrum();
	
	    System.out.println("--------------------组建一支流行乐队-----------------------");
	    PopBankFactory popBand = new PopBankFactory();
	    popBand.createGuitar().getGuitar();
	    popBand.createBass().getBass();
	    popBand.createDrum().getDrum();
    }   
}

Output

--------------------组建一支摇滚乐队-----------------------
Guitar:ESP
Bass:ESP
Drum:Gretsch
--------------------组建一支流行乐队-----------------------
Guitar:Fender
Bass:Fender
Drum:Roland

4.总结

  • 一般抽象工厂模式都是适用于生产多个产品的组合对象时使用
  • 抽象工厂模式可以有多个工厂类,有点与简单工厂相同,不过他可以提供多个产品对象,而不是单一的产品对象
  • 如果新增产品,则依然需要修改抽象工厂和具体的工厂类,依旧违反开闭原则