【云+社区年度征文】设计模式-工厂模式(简单工厂、工厂方法、抽象工厂)

简单工厂


简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是**由一

个工厂对象决定创建出哪一种产品类的实例**。定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)。当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

由于创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法模式(Static Factory Method)。

  • Product表示产品接口,也可用抽象类实现,封装产品间共有的属性。
  • ConcreteProduct*表示具体的实际产品。
  • Factory表示工厂,工厂根据需要来创建相应的产品。

这样一来,当添加新的产品C时,只需要修改工厂部分代码即可,而传统方法需要在每一个创建产品的地方都进行修改。可以理解为把具体的产品创建封装成一个工厂类。

举个例子,大富翁的地图创建:

  • AbstractBlock是接口,表示抽象的地块,包括方法printBlock()打印地块。
  • Empty、Prison、Park实现上述接口,表示空地(*)、监狱(&)和公园(#)。
  • SimpleFactory是创建地块的简单工厂。

类图:

代码:

  1. 产品接口
代码语言:txt
复制
public interface AbstractBlock {
    public void printBlock();
}
  1. 产品接口实现子类
代码语言:txt
复制
public class Empty implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("* ");
    }
}
代码语言:txt
复制
public class Park implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("# ");
    }
}
代码语言:txt
复制
public class Prison implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("& ");
    }
}
  1. 简单工厂类
代码语言:txt
复制
public class SimpleFactory {
    public AbstractBlock getBlock(String type){ //根据传参创建不同的地块
        if(type.equalsIgnoreCase("Empty")){
            return new Empty();
        } else if(type.equalsIgnoreCase("Park")){
            return new Park();
        } else if(type.equalsIgnoreCase("Prison")){
            return new Prison();
        }
        return null;
    }
}
  1. 调用工厂
代码语言:txt
复制
public class Map {
    public void getMap(){
        SimpleFactory simpleFactory=new SimpleFactory();  //实例化工厂
        ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();  //地块集合
    String []types=new String[3];
    types[0]=&#34;Empty&#34;;
    types[1]=&#34;park&#34;;
    types[2]=&#34;Prison&#34;;
    Random rd = new Random();
    for(int i=1;i&lt;=12;i++){  //随机用工厂创建地块并放入集合
        int tt = rd.nextInt(types.length);
        map.add(simpleFactory.getBlock(types[tt]));
    }
    //地图大小写死了,不是重点
    for(int i=0;i&lt;12;i++){
        map.get(i).printBlock();
        if(i==3||i==5||i==7)
            System.out.println();
        if(i==4||i==6)
            System.out.print(&#34;    &#34;);
    }
}

}

  1. 测试
代码语言:txt
复制
public class MonoPoly {
public static void main(String[] args) {
Map map=new Map();
map.getMap();
}
}
  1. 运行结果

工厂方法


不难发现,当增加新的产品时需要对简单工厂类修改,或创建多个简单工厂。(比如增加一个法院地块)

工厂方法进一步解耦合,把工厂类抽象,不再负责所有实例的创建,而是把具体的创建工作交给了子类去完成,实例化延迟到子类加载,由子类来决定要实例化的类。

抽象化工厂类,把具体实例化工作交给其子类实现。

代码:

  1. 工厂接口
代码语言:txt
复制
public interface AbstractFactory {
    public AbstractBlock createBlock();
}
  1. 工厂实现子类
代码语言:txt
复制
public class EmptyFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
    return new Empty();
}

}

代码语言:txt
复制
public class ParkFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
return new Park();
}
}
代码语言:txt
复制
public class PrisonFactory implements AbstractFactory {
@Override
public AbstractBlock createBlock() {
return new Prison();
}
}
  1. 产品接口
代码语言:txt
复制
public interface AbstractBlock {
public void printBlock();
}
  1. 产品实现子类
代码语言:txt
复制
public class Empty implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("* ");
}
}
代码语言:txt
复制
public class Park implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("# ");
}
}
代码语言:txt
复制
public class Prison implements AbstractBlock {
@Override
public void printBlock() {
System.out.print("& ");
}
}
  1. 调用
代码语言:txt
复制
public class Map {
public void getMap() {
ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>(); //地块集合
AbstractFactory abstractFactory;

    Random rd = new Random();
    for(int i=1;i&lt;=12;i++){  //随机用工厂创建地块并放入集合
        int tt = rd.nextInt(3);
        if(tt==0)abstractFactory=new EmptyFactory();
        else if(tt==1)abstractFactory=new ParkFactory();
        else abstractFactory=new PrisonFactory();
        map.add(abstractFactory.createBlock());
    }
    //地图大小写死了,不是重点
    for(int i=0;i&lt;12;i++){
        map.get(i).printBlock();
        if(i==3||i==5||i==7)
            System.out.println();
        if(i==4||i==6)
            System.out.print(&#34;    &#34;);
    }
}

}

  1. 测试
代码语言:txt
复制
public class MonoPoly {
public static void main(String[] args) {
Map map=new Map();
map.getMap();
}
}

运行结果:

抽象工厂


不难发现当创建新的产品接口时,也需要对工厂方法修改,或创建多个工厂方法。(比如增加魔法地块簇,对应组产品魔法公园、魔法空地、魔法监狱等)

抽象工厂将工厂方法进一步抽象。定义了一个接口用于创建相关或有依赖关系的对象簇,而无需指明具体的类。可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

把工厂类抽象后,对应不同子类工厂(普通/魔法),生产对应的一组产品。最后调用时统一调用抽象接口即可,不必知道具体对象,面向接口编程。

  1. 产品接口
代码语言:txt
复制
public interface AbstractBlock {
void printBlock();
}
  1. 产品抽象子类-普通产品
代码语言:txt
复制
public abstract class NormalAbstractBlock implements AbstractBlock {
public abstract void printBlock();
}

2.2普通空地

代码语言:txt
复制
public class NormalEmpty extends NormalAbstractBlock {
public void printBlock() {
System.out.print("* ");
}
}

2.3普通公园

代码语言:txt
复制
public class NormalPark  extends NormalAbstractBlock {
public void printBlock() {
System.out.print("# ");
}
}

2.4普通监狱

代码语言:txt
复制
public class NormalPrison extends NormalAbstractBlock {
public void printBlock() {
System.out.print("& ");
}
}
  1. 产品抽象子类-魔法产品
代码语言:txt
复制
public abstract class MagicAbstractBlock implements AbstractBlock {
public abstract void printBlock();
}

3.2魔法空地

代码语言:txt
复制
public class MagicEmpty  extends MagicAbstractBlock {
public void printBlock() {
System.out.print("e ");
}
}

3.3魔法公园

代码语言:txt
复制
public class MagicPark extends MagicAbstractBlock {
public void printBlock() {
System.out.print("g ");
}
}

3.4魔法监狱

代码语言:txt
复制
public class MagicPrison extends MagicAbstractBlock {
public void printBlock() {
System.out.print("p ");
}
}
  1. 工厂接口
代码语言:txt
复制
public interface AbstractFactory {
AbstractBlock getEmpty();
AbstractBlock getPrison();
AbstractBlock getPark();
}
  1. 工厂实现子类-普通工厂
代码语言:txt
复制
public class NormalFactory implements  AbstractFactory {
public AbstractBlock getEmpty() { return new NormalEmpty(); }
public AbstractBlock getPrison() { return new NormalPrison(); }
public AbstractBlock getPark() { return new NormalPark(); }
}
  1. 工厂实现子类-魔法工厂
代码语言:txt
复制
public class MagicFactory implements AbstractFactory {
public AbstractBlock getEmpty() { return new MagicEmpty(); }
public AbstractBlock getPrison() {return new MagicPrison(); }
public AbstractBlock getPark() { return new MagicPark(); }
}
  1. 调用
代码语言:txt
复制
public class Map {
public void getMap(AbstractFactory af){
ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();
map.add(af.getEmpty());
map.add(af.getPrison());
map.add(af.getPark());
Random rd = new Random(3);
int col=12;
for(int i=1;i<=col;i++){
int tt = rd.nextInt(3);
map.get(tt).printBlock();
if(i==4||i==6||i==8)
System.out.println();
if(i==5||i==7)
System.out.print(" ");
}
}
}
  1. 测试
代码语言:txt
复制
public class Monopoly {
public void play(){
Map map=new Map();
Scanner scan = new Scanner(System.in);
System.out.println("请输入指令(1输出普通地图,2输出魔法地图)");
int order;
order = scan.nextInt();
if(order == 1){
map.getMap(new NormalFactory());
}else{
map.getMap(new MagicFactory());
}
}
}

运行结果:

原创不易,请勿转载本不富裕的访问量雪上加霜

博主首页:https://wzlodq.blog.csdn.net/

微信公众号:唔仄lo咚锵

如果文章对你有帮助,记得一键三连❤