工厂模式(将创建对象的逻辑封装进工厂)
场景:披萨订购
简单工厂模式
不要把大量的分支杂糅到业务代码中,把这种逻辑分离出来
把根据……创建……的逻辑封装到一个工厂里面,然后调用工厂拿到对象(这里要依赖接口)。这个工厂可以使用聚合从外部传入,由驱动类创建工厂对象。如果这个工厂是唯一的,我们可以将创建对象的方法也设置为static,这样就可以直接调用这个类的方法而不需要创建这个工厂对象
静态工厂,缺点是披萨属性特别多时,需要编写大量的披萨类,维护起来比较麻烦
抽象工厂
简单工厂只有一个工厂,要把所有的Bean的创建都集中在这一个工厂里面,显得有些冗杂,比如下面这个例子,一共有四个披萨,如果要用简单工厂就要写四个if-else,假如以后影响披萨种类的因素变多,每种因素都要自由组合,最后披萨的数量就会非常之多。本质上是没有将影响披萨的因素分离出来而是去枚举每一种可能出现的披萨。而抽象方法模式则是按照某些影响因素将工厂分为几个具体的工厂(工厂子类簇),每个工厂再按照逻辑创建bean,而至于按照什么因素将工厂分类就要具体情况具体分析。这样即使Bean的种类很多,不同种类的Factory创建Bean的过程是互不干扰的,可以让程序的结构更加清晰(前提是划分工厂的依据合理)。所以抽象工厂本质上就是对工厂进行了分类,假如bean很多很多,只用一个工厂来创建bean会使得这个工厂有些臃肿,这时候可以考虑将这个简单工厂拆分成若干不同类别的工厂,也就成了抽象工厂,基类保留创建bean的公共部分,具体的实现类再去保留个性的部分
interface Pizza{
void make();
void bake();
void cut();
void send();
}
abstract class AbstractPizza implements Pizza{
@Override
public void bake() {
System.out.println("烘烤");
}
@Override
public void cut() {
System.out.println("切分");
}
@Override
public void send() {
System.out.println("送达");
}
}
class BeijingCheesePizza extends AbstractPizza{
@Override
public void make() {
System.out.println("make BeijingCheesePizza");
}
}
class ShanghaiCheesePizza extends AbstractPizza{
@Override
public void make() {
System.out.println("make ShanghaiCheesePizza");
}
}
class BeijingZhishiPizza extends AbstractPizza{
@Override
public void make() {
System.out.println("make BeijingZhishiPizza");
}
}
class ShanghaiZhishiPizza extends AbstractPizza{
@Override
public void make() {
System.out.println("make ShanghaiZhishiPizza");
}
}
abstract class AbstractPizzaFactory{
abstract Pizza createPizza(String tasteType);
}
class BeijingPizzaFactory extends AbstractPizzaFactory{
@Override
Pizza createPizza(String tasteType) {
switch (tasteType){
case "cheese":
return new BeijingCheesePizza();
case "zhishi":
return new BeijingZhishiPizza();
default:
return null;
}
}
}
class ShanghaiPizzaFactory extends AbstractPizzaFactory{
@Override
Pizza createPizza(String tasteType) {
switch (tasteType){
case "cheese":
return new ShanghaiCheesePizza();
case "zhishi":
return new ShanghaiZhishiPizza();
default:
return null;
}
}
}
public class PizzaFactoryDemo {
public static AbstractPizzaFactory pizzaFactory;
public static AbstractPizzaFactory getPizzaFactory(String location){
switch (location){
case "Beijing":
return new BeijingPizzaFactory();
case "Shanghai":
return new ShanghaiPizzaFactory();
default:
return null;
}
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String pizzaLocation = scanner.nextLine();
pizzaFactory=getPizzaFactory(pizzaLocation);
while(scanner.hasNext()){
Pizza pizza= pizzaFactory.createPizza(scanner.nextLine());
if(pizza!=null) {
pizza.make();
pizza.bake();
pizza.cut();
pizza.send();
}else{
System.out.println("没有这种披萨");
}
}
}
}
小结
如果Bean的种类很少使用简单工厂,Bean的种类很多使用抽象工厂