创建型模式之工厂模式

工厂模式

1. 简单工厂模式

2. 工厂方法

3. 抽象工厂模式

1.简单工厂模式(Simple Factory pattern)

属于类的创新型模式,又叫静态工厂方法模式(Static Factory Method Pattern);是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

① 工厂角色(SimpleFactory)

这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑,当然工厂类必须能够被外界调用,创建所需要的产品对象。

抽象(IProduct)产品角色

简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。

③具体产品(Concrete Product)角色

简单工厂所创建的具体实例对象,这些具体的产品往往拥有共同的父类。

简单工厂模式优点:

直接创建所需实例,无需了解对象是如何创造以及如何组织的,有利于整个软件体系的优化。

简单工厂模式缺点:

工厂类集中了所有实例的创建逻辑,一旦该工厂出现问题,所有客户端都将受到牵连。更重要的是违背了“开放封闭原则”。

简单工厂模式实例:

抽象产品角色:

package com.szxy.LemonSnm;

public interface IFood {
           void eat();   //抽象产品 可以吃
}

具体产品角色1(薯条)

package com.szxy.LemonSnm;
/*
薯条
 */
public class Chips implements IFood{

    @Override
    public void eat() {
        System.out.println("我们吃到了薯条");
    }
}

具体产品角色2(麦香鸡)

package com.szxy.LemonSnm;
/*
麦香鸡
 */
public class McChickn implements IFood {

    @Override
    public void eat() {
        System.out.println("我们吃到了麦香鸡");
    }
}

工厂角色(麦当劳商店)

package com.szxy.LemonSnm;
   /*
   麦当劳
    */
public class McDonlad {
          public IFood getFood(String name){
                   switch(name){
                       case "chip":
                        return new Chips();
                       case "mcChicken":
                           return new McChickn();
                           default:
                               System.out.println("不能提供此产品");
                               return null;
                   }
          }
}

客户端测试

package com.szxy.LemonSnm;

public class Client {
    public static void main(String[] args) {
        System.out.println("this is Simple Factory main");

        McDonlad mcDonlad = new McDonlad(); //创建消费者
        IFood food = mcDonlad.getFood("chip");//购买薯条
        if (food !=null){
            food.eat();
        }

        food = mcDonlad.getFood("mcChicken");//购买麦香鸡
        if (food !=null){
            food.eat();
        }

        food = mcDonlad.getFood("flsChicken");//购买符离集烧鸡
        if (food !=null){
            food.eat();
        }
    }
}

2、工厂方法

一个抽象产品派生出多个具体产品类;一个抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。
既定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类),“一对一”的关系。

① 工厂接口

工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来与调用者交互的接口,其本质上是一样的。

②工厂实现

在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要多少个具体的工厂实现。

③产品接口

主要目的是定义产品的规范,所有产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。

④产品实现

实现产品接口的具体类,决定了产品在客户端的具体行为。

工厂方法优点:

①在工厂方法中,用户只需要知道所有产品的具体工厂,无须关心具体的创建过程,甚至不需要具体产品类的类名。

②在系统中增加新产品时,只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。

工厂方法缺点:

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,那么系统类中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

工厂方法与简单工厂对比:

工厂方法模式是简单工厂模式的延伸。在工厂方法模式中,核心工厂类不在负责产品的创建,而是将具体的创建工作交给子类去完成。也就是核心工厂仅仅只是提供创建的接口,具体实现方法交给继承它的子类去完成。
当我们的系统需要增加其他新的对象时,我们只需要添加一个具体的产品和它的创建工厂即可,不需要对原工厂进行任何修改,这样很好地符合了“开闭原则”。

工厂方法实例:

UML图

工厂接口(抽象商店):

package com.szxy.LemonSnm;

public interface Store {
    IChips setFood();//生产食物
}

工厂1实现(必胜客商店):

package com.szxy.LemonSnm;

public class BscStore implements  Store {
    @Override
    public IChips setFood() {
        System.out.println("生产了必胜客薯条");
        return new BscoChips();
    }
}

工厂2实现(肯德基商店):

package com.szxy.LemonSnm;

public class CosChips implements IChips{
    @Override
    public void eat() {
        System.out.println("吃到了肯德基的薯条");
    }
}

工厂3实现(麦当劳商店):

package com.szxy.LemonSnm;

public class McStore implements Store {
    @Override
    public IChips setFood() {
        System.out.println("产生了麦当劳薯条");
        return new McChips();
    }
}

产品接口(抽象产品薯条):

package com.szxy.LemonSnm;

public interface IChips {
    public void eat();//吃到薯条
}

产品1实现(必胜客薯条):

package com.szxy.LemonSnm;

public class BscoChips implements IChips {
    @Override
    public void eat() {
        System.out.println("吃到了必胜客的薯条");
    }
}

产品2实现(肯德基薯条):

package com.szxy.LemonSnm;

public class CosChips implements IChips{
    @Override
    public void eat() {
        System.out.println("吃到了肯德基的薯条");
    }
}

产品3实现(麦当劳薯条):

package com.szxy.LemonSnm;

public class McChips implements IChips{
    @Override
    public void eat() {
        System.out.println("吃到了麦当劳的薯条");
    }
}

客户端测试

package com.szxy.LemonSnm;

public class Client {
    public static void main(String[] args) {
        System.out.println("this is Factory Method main");
        Store store = new CosStore();   //肯德基商店
        store.setFood().eat();
         store = new McStore();         //麦当劳商店
        store.setFood().eat();
         store = new BscStore();      //必胜客商店
        store.setFood().eat();
    }
}

3、抽象工厂

多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可以创建多个具体产品类的实例。
既提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。

三者比较:

他们都属于工厂模式,在形式和特点上也是极为相似的,最总目的都是为了解耦。
在使用中,不必在意这个模式是工厂方法模式还是抽象工厂模式,他们之间可以互相转换。所以,在使用工厂模式时,只需要关心是否降低了耦合度。

工厂接口(抽象商店):

package com.szxy.LemonSnm;

public interface Store {
    IChips setFood();//生产食物
    Coke   setCoke(); //生产可乐
}

工厂1实现(肯德基商店):

package com.szxy.LemonSnm;

public class CosChips implements IChips{
    @Override
    public void eat() {
        System.out.println("吃到了肯德基的薯条");
    }
}

产品1实现(肯德基薯条):

package com.szxy.LemonSnm;

public class CosChips implements IChips{
    @Override
    public void eat() {
        System.out.println("吃到了肯德基的薯条");
    }
}

产品2实现(肯德基可乐):

package com.szxy.LemonSnm;

public class CosCoke implements Coke {
    @Override
    public void eat() {
        System.out.println("我们喝到了肯德基的可乐");
    }
}

客户端测试:

package com.szxy.LemonSnm;

public class Client {
    public static void main(String[] args) {
        System.out.println("this is Abstract Factory main");

        //想喝肯德基可乐
        Store store = new CosStore(); //有个肯德基商店
        Coke coke = store.setCoke();  //生产可乐
        coke.eat();   //喝可乐

        //想吃肯德基薯条
        store = new CosStore();  //有个肯德基商店
        IChips iChips = store.setFood();   //生产薯条
        iChips.eat();   //吃薯条


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值