工厂模式

为什么要使用工厂模式:

工厂模式归根到底,就是将项目主程序中,对象实例化部分抽取出来,从而达到跟主程序解构,以便于项目以后拥有更好的扩展性和维护性。

 

简单工程模式:

通俗点讲,就是将程序中碰到if...new  if...new 的代码提炼到一个静态工厂里面进行实现,这样做的好处以后新增加一种类型对象,不需要调整主程序,只需要调整静态工厂即可。

UML图示:

需要获取类具体实例的程序,通过给简单工厂传入需要具体实例化对象的标记,简单工厂根据标记,new出具体对象返回给使用者。

代码示例:

 假设需求是这样的,类似宜家一样,用户逛完商店后,记录需要购买的商品的名字,将购买单给服务员,服务员在系统输入商品名字,系统自动带出商品的位置。

需求分析:商品是可变的,而系统定位商品功能这个主程序功能是固定的,是不可变的,需要将可变的商品提炼出来,和主程序解构,以便后期商品的维护和扩展。用简单工厂实现代码如下:

商品抽象类:

public abstract class Produce {
    //获取商品位置
    public abstract void getProduce();

}

具体商品1:

public class NuomilaChair extends Produce {
    public void getProduce() {
        System.out.println("诺米拉椅子放在三区12号位置");
    }
}

具体商品2:

public class AigeChair extends Produce {

    public void getProduce() {
        System.out.println("爱格椅子放在三区11号位置");
    }

}

简单工厂类:

public class SimpleFactory {
    public Produce findProduce(String name) {
        Produce produce = null;
        //新增加商品只需要在工厂类调整,不需要调整主程序代码,实现解耦。
        if (name.equals( "Aige")) {
            produce = new AigeChair();
        } else if (name.equals("Nuomila")) {
            produce = new NuomilaChair();
        }
        return produce;
    }

}

系统类:

public class ProduceSystem {
    SimpleFactory sf = null;

    public ProduceSystem(SimpleFactory sf) {
        this.sf = sf;
    }

    public void runSystem() {
        Produce pro = null;
        String proName = null;
        do {
            try {
                proName = getProduceName();
                pro = this.sf.findProduce(proName);
                pro.getProduce();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("输入有误或者不存在该商品!");
            }
        } while (true);
    }

    private String getProduceName() {
        String str = null;
        System.out.println("请输入商品名字:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            str = br.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return str;
    }
}

 

启动程序:

    public static void main(String[] args) {
        new ProduceSystem(new SimpleFactory()).runSystem();
    }

工厂模式:

      定义了一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法将对象实例化推迟到子类。基于上面讲到的简单工厂方法,即将SimpleFactory设计为抽象方法,由子类继承后实现具体方法。

UML图示 :

实际上就是基于简单工厂,将简单工厂这种静态工厂抽象化,变得更加灵活和可扩展性

代码示例:

基于上面需求,现在该商场是连锁店,每个店的商品的在仓库的摆放位置都不一样,很明显之前的代码很难满足需求,需要将上面的简单工厂进行抽象化,每家连锁店各自实现商品的摆放位置。

代码如下:

商品抽象类:

public abstract class Produce {
    //获取商品位置
    public abstract void getProduce();

}

商品1:

public class AigeChairA extends Produce {

    public void getProduce() {
        System.out.println("爱格椅子放在三区11号位置");
    }

}

商品2:

public class AigeChairB extends Produce {

    public void getProduce() {
        System.out.println("爱格椅子放在一区11号位置");
    }

}

商品3:

public class NuomilaChairA extends Produce {
    public void getProduce() {
        System.out.println("诺米拉椅子放在三区12号位置");
    }
}

商品4:

public class NuomilaChairB extends Produce {
    public void getProduce() {
        System.out.println("诺米拉椅子放在二区12号位置");
    }
}

工厂超类:

public abstract class Factory {
    public abstract Produce findProduce(String name);
}

工厂A:

public class FactoryA extends Factory {

    @Override
    public Produce findProduce(String name) {
        Produce produce = null;
        //每个工厂各自维护自己的商品
        if (name.equals( "Aige")) {
            produce = new AigeChairA();
        } else if (name.equals("Nuomila")) {
            produce = new NuomilaChairA();
        }
        return produce;
    }

}

工厂B:

public class FactoryB extends Factory {

    @Override
    public Produce findProduce(String name) {
        Produce produce = null;
        //每个工厂各自维护自己的商品
        if (name.equals( "Aige")) {
            produce = new AigeChairB();
        } else if (name.equals("Nuomila")) {
            produce = new NuomilaChairB();
        }
        return produce;
    }

}

系统类:

public class ProduceSystem {
    Factory sf = null;

    public ProduceSystem(Factory sf) {
        this.sf = sf;
    }

    public void runSystem() {
        Produce pro = null;
        String proName = null;
        do {
            try {
                proName = getProduceName();
                pro = this.sf.findProduce(proName);
                pro.getProduce();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("输入有误或者不存在该商品!");
            }
        } while (true);
    }

    private String getProduceName() {
        String str = null;
        System.out.println("请输入商品名字:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            str = br.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return str;
    }

    
}

启动类:

public static void main(String[] args) {
        new ProduceSystem(new FactoryA()).runSystem();
    }

抽象工厂模式

  定义了接口用于创建相关或者有依赖依赖关系的对象族,而无需指定具体类

UML图示:

 和工厂模式对比,工厂不是只是生产一类产品,而是生成多种不通种类的产品。

代码示例:

  基于上面需求,商店定义,该连锁店的商品,只固定卖椅子,床.....等,每家连锁店只能在这些商品。(注意,抽象工厂模式在抽象工厂里面定一个的产品组合后,后续如果需要调整的话,极其麻烦)

商品抽象类A:

public abstract class Bed {
//获取商品位置
public abstract void getProduce();

}

 

商品抽象类B:

public abstract class Chair {
//获取商品位置
public abstract void getProduce();

}

 

商品A具体类1:

public class BedA extends Bed {

public void getProduce() {
System.out.println("百灵床放在一区10号位置");
}

}

商品A具体类2:

public class BedB extends Bed {
    public void getProduce() {
        System.out.println("马尔姆放在三区17号位置");
    }
}

商品B具体类1:

public class ChairA extends Chair {

    public void getProduce() {
        System.out.println("爱格椅子放在三区11号位置");
    }

}

商品B具体类2:

public class ChairB extends Chair {
    public void getProduce() {
        System.out.println("诺米拉椅子放在二区12号位置");
    }
}

工厂抽象类:

public abstract class Factory {
    public abstract Chair findChair();
    public abstract Bed findBed();

}

具体工厂类A:

public class FactoryA extends Factory {

    @Override
    public Chair findChair() {
        
        return new ChairA();
    }

    @Override
    public Bed findBed() {
        
        return new BedA();
    }

    

}

具体工厂类B:

 

public class FactoryB extends Factory {

    @Override
    public Chair findChair() {
        // TODO Auto-generated method stub
        return new ChairB();
    }

    @Override
    public Bed findBed() {
        // TODO Auto-generated method stub
        return new BedB();
    }



}

系统类:

public class ProduceSystem {
    Factory sf = null;

    public ProduceSystem(Factory sf) {
        this.sf = sf;
    }

    public void runSystem() {
        Chair proCha = null;
        Bed  proBed=null;
        String proName = null;
            try {
                proCha = this.sf.findChair();
                proBed = this.sf.findBed();
                proCha.getProduce();
                proBed.getProduce();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("输入有误或者不存在该商品!");
            }
    }
}

启动:

public static void main(String[] args) {
        new ProduceSystem(new FactoryA()).runSystem();
    }

工厂模式和抽象工厂区别:

抽象工程关键在于产品之间的抽象关系,所以至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品。也就是对于工厂模式,如果对产品进行分类区分的话,为抽象工厂,如果不进行分类,统一为产品,即为工厂模式。

posted @ 2017-05-02 15:07  葡萄树上有葡萄  阅读(208)  评论(0)    收藏  举报