工厂模式
简单工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪个类(也可以叫做静态工厂模式)
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.总结
- 一般抽象工厂模式都是适用于生产多个产品的组合对象时使用
- 抽象工厂模式可以有多个工厂类,有点与简单工厂相同,不过他可以提供多个产品对象,而不是单一的产品对象
- 如果新增产品,则依然需要修改抽象工厂和具体的工厂类,依旧违反开闭原则