设计模式----工厂模式

简介

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。常用的设计模式之一。

涉及角色

  • creator
    抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创建对象的工厂类必须实现这个接口。不使用new关键字来生成实例,而是调用生成市里的专用方法来生成实例,这样就可以防止父类与其他具体类的耦合。
  • ConcreteCreator
    具体工厂角色:担任这个角色的是实现了抽象工厂接口的具体Java类,具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。
  • Product
    抽象产品角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
  • ConcreteProduct
    具体产品角色:这个角色实现了抽象产品角色所申明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。

UML

这里写图片描述

使用场景

出现了大量的对象需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建对象。

优点

  • 可以使代码结构清晰,有效地封装变化
  • 对调用者屏蔽具体类,只需要关心对应的接口
  • 降低耦合度
  • 多态性,与特定应用无关,适用于任何实体类

缺点

  • 每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量
  • 工厂类集中了所有创建逻辑,若异常,影响整个系统运行

代码示例

如:车间主要是生产容器的,车间内存在数条产品线,分别生产瓶子、水杯、罐头盒等,用工厂类实现
定义容器接口

package com.designpattern.factory;
public interface Container {
    public void getName();
    public void getShap();
    public void getColor();
}

具体产品实现Container接口

package com.designpattern.factory;

public class Bottle implements Container {

    @Override
    public void getName() {
        // TODO Auto-generated method stub
        System.err.println("bottle name:bottle");
    }

    @Override
    public void getShap() {
        // TODO Auto-generated method stub
        System.err.println("bottle shap:cylinder");
    }

    @Override
    public void getColor() {
        // TODO Auto-generated method stub
        System.err.println("bottle Color:black");
    }

}
package com.designpattern.factory;

public class Cup implements Container {

    @Override
    public void getName() {
        // TODO Auto-generated method stub
        System.err.println("Cup name:Cup");
    }

    @Override
    public void getShap() {
        // TODO Auto-generated method stub
        System.err.println("Cup shap:cylinder");
    }

    @Override
    public void getColor() {
        // TODO Auto-generated method stub
        System.err.println("Cup Color:white");
    }

}
package com.designpattern.factory;

public class Can implements Container {

    @Override
    public void getName() {
        // TODO Auto-generated method stub
        System.err.println("can name:can");
    }

    @Override
    public void getShap() {
        // TODO Auto-generated method stub
        System.err.println("can shap:cycle");
    }

    @Override
    public void getColor() {
        // TODO Auto-generated method stub
        System.err.println("can color:green");
    }

}

创建一个生产容器的工厂,有一下几种方式

  • 普通工厂方式,即简单工厂
package com.designpattern.factory;

public class Factory {
    public Container getProduct(String productType) {
        if (productType.equalsIgnoreCase("cup")) {
            return new Cup();
        } else if (productType.equalsIgnoreCase("can")) {
            return new Can();
        }else if (productType.equalsIgnoreCase("bottle")) {
            return new Bottle();
        } else {
            return null;
        }

    }
}

简单工厂缺点很明显,需要显式传入控制变量,如果传入有误,则不能正确创建需要的对象

  • 多工厂方法
package com.designpattern.factory;

public class MulitFactoryMethod {
    public Container getCup() {
        return new Cup();
    }
    public Container getBottle() {
        return new Bottle();
    }
    public Container getCan() {
        return new Can();
    }
}
  • 静态工厂
package com.designpattern.factory;

public class StaticFactory {
    public static Container getCup() {
        return new Cup();
    }
    public static Container getBottle() {
        return new Bottle();
    }
    public static Container getCan() {
        return new Can();
    }
}

建立测试类

package com.designpattern.factory;

public class TestMain {

    public static void main(String[] args) {
        //测试普通工厂创建对象
        Factory factory = new Factory();
        factory.getProduct("cup").getName();    
        //测试多工厂创建对象
        MulitFactoryMethod mulitFactoryMethod = new MulitFactoryMethod();
        mulitFactoryMethod.getCan().getName();
        //测试静态工厂创建对象
        StaticFactory.getBottle().getName();
    }
}
Cup name:Cup
can name:can
bottle name:bottle

猜你喜欢

转载自blog.csdn.net/yue530tomtom/article/details/79485322