简单工厂-工厂方法-抽象工厂对比,给出理解思路和Java参考案例源码

以去餐厅吃饭为例。理解一下简单工厂-工厂方法-抽象工厂的区别于关联。


1.   简单工厂

由一个工厂对象决定创建出哪一种产品类的实例。

  • 一个具体工厂通过条件语句创建多个产品,产品的创建逻辑集中与一个工厂类。
  • 客户端通过传不同的参数给工厂,实现创建不同产品的目的
  • 增加新产品时,需要修改工厂类、增加产品类,不符合OCP原则


人去吃食物(酒,肉),店只有一家,需要指定要什么。好比餐厅就一个厨房,同时提供酒和肉。

Factory根据出入的参数直接创建出ConcreteFood


abstract class Food{

    public abstract String getEatable();

}

class Alcohol extends Food{

    public String getEatable(){

        return"alcohol";

    }

}

class Meat extends Food{

    public String getEatable(){

        return"meat";

    }

}

class Factory{

    public Food getFood(String food)throws Exception{

        if(food.equals("alcohol")){

            return new Alcohol();

        }else if(food.equals("meat")){

            return new Meat();

        }

        throw new Exception("No "+food);

    }

}

 

public class Man{

    public void eat(){

        Factory factory=new Factory();

        Food food=null;

        //eat alcohol

        try {

            food=factory.getFood("alcohol");

        } catch (Exception e) {

            e.printStackTrace();

        }

        print(food.getEatable());

        //eat meat

        try {

            food=factory.getFood("meat");

        } catch (Exception e) {

            e.printStackTrace();

        }

        print(food.getEatable());

    }

    public void print(String str){

        System.out.println("I eat "+str+" .");

    }

    public static void main(String[] args){

        Man man=new Man();

        man.eat();

    }

}

 

输出:

I eat alcohol .

I eat meat .

 

2.   工厂方法:

  • 一个工厂创建一个产品,所有的具体工厂继承自一个抽象工厂。
  • 客户端先创建不同产品的工厂,再由工厂创建具体产品,产品的创建逻辑分散在每个具体工厂类中。
  • 客户端只依赖于抽象工厂与抽象产品,不依赖任何具体的工厂与具体产品
  • 增加新产品时,需要增加工厂类和产品类,符合OCP原则

人去吃食物(酒,肉),店只有两家,一家只卖酒,一家只卖肉,不需要指定要什么,只要走到需要买食物的那家就行了。好比餐厅有多个厨房,每个厨房有分工,只提供一种食物,而不需要在一个厨房里面拥挤地摆放多种食物。

工厂方法在简单工厂之上,工厂方法将产品的具体创建给子类完成,这样在需要增加食物种类时,不用修改Factory,只需要添加相应的ConcreteFactoryConcreteFood.

 

abstract class Food{

    public abstract String getEatable();

}

class Alcohol extends Food{

    public String getEatable(){

        return"alcohol";

    }

}

class Meat extends Food{

    public String getEatable(){

        return"meat";

    }

}

abstract class Factory{

    public abstract Food getFood();

}

 

class AlcoholFactory extends Factory{

    public Food getFood(){

        return new Alcohol();

    }

}

 

class MeatFactory extends Factory{

    public Food getFood(){

        return new Meat();

    }

}

 

public class Man{

    public void eat(){

        Factory factory=null;

        Food food=null;

        //eat alcohol

        factory=new AlcoholFactory();

        food=factory.getFood();

        print(food.getEatable());

        //eat meat

        factory=new MeatFactory();

        food=factory.getFood();

        print(food.getEatable());

    }

    public void print(String str){

        System.out.println("I eat "+str+" .");

    }

    public static void main(String[] args){

        Man man=new Man();

        man.eat();

    }

}



 输出:

I eat alcohol .

I eat meat  .

 

3.   抽象工厂

  •  一个具体工厂创建一个产品族,一个产品族是不同系列产品的组合,产品的创建的逻辑分在在每个具体工厂类中。所有的具体工厂继承自同一个抽象工厂。
  • 客户端创建不同产品族的工厂,产品族的工厂创建具体的产品对客户端是不可见的。
  • 增加新的产品族时,需要增加具体工厂类,符合OCP原则。
  • 增加新产品时,需要修改具体工厂类和增加产品类,不符合OCP原则
  • 如果没有应对多系列对象创建的需求变化,则没有必要使用抽象工厂模式,这时候使用简单的静态工厂完全可以。

人去吃食物(酒,肉),店只有两家,一家只卖酒,一家只卖肉,不需要指定要什么,只要走到需要买食物的那家就行了。但是不能用手拿着吃吧,在买酒的时候,同时买个杯子;在买肉的时候,同时买个小刀。好比是每个厨房除了提供对应食物,还提供与该食物匹配的其他服务,比方说餐具,即把高内聚封装。

抽象工厂在工厂方法之上,主要针对于创建多个不同的产品族,而不是只有Food,还有TableWare。我理解的抽象工厂创建的是一整个体系,而不是单一的功能,就像是饭店,提供给你整个餐饮服务,有食物,餐具,包厢,工厂方法就像是餐厅里面的厨房,只提供食物。

 

abstract class Food{

    public abstract String getEatable();

}

class Alcohol extends Food{

    public String getEatable(){

        return"alcohol";

    }

}

class Meat extends Food{

    public String getEatable(){

        return"meat";

    }

}

abstract class TableWare{

    public abstract String getTool();

}

class Cup extends TableWare{

    public String getTool(){

        return"cup";

    }

}

class Knife extends TableWare{

    public String getTool(){

        return"knife";

    }

}

abstract class Factory{

    public abstract Food getFood();

    public abstract TableWare getTableWare();

}

 

class AlcoholFactory extends Factory{

    public Food getFood(){

        return new Alcohol();

    }

    public TableWare getTableWare(){

        return new Cup();

    }

}

 

class MeatFactory extends Factory{

    public Food getFood(){

        return new Meat();

    }

    public TableWare getTableWare(){

        return new Knife();

    }

}

 

public class Man{

    public void eat(){

        Factory factory=null;

        Food food=null;

        TableWare tableWare=null;

        //eat alcohol

        factory=new AlcoholFactory();

        food=factory.getFood();

        tableWare=factory.getTableWare();

       print(food.getEatable(),tableWare.getTool());

        //eat meat

        factory=new MeatFactory();

        food=factory.getFood();

        tableWare=factory.getTableWare();

       print(food.getEatable(),tableWare.getTool());

    }

    public void print(String food,String tableWare){

        System.out.println("I eat "+food+" by "+tableWare+" .");

    }

    public static void main(String[] args){

        Man man=new Man();

        man.eat();

    }

}

 

输出:

I eat alcohol by cup .

I eat meat by knife .

 

 

参考:

http://blog.csdn.net/dylan_ren/article/details/1680430

http://tech.ddvip.com/2012-10/1350629930183788_2.html


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值