Java设计模式-工厂模式

简单工厂模式(创建型)

又叫静态工厂,如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于设计模式 的 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”。

而工厂模式是多个工厂,增加、删除、修改产品就只需要修改工厂类。

定义:定义了一个创建对象的类,由这个类来封装实例化对象的行为。

实例化对象的时候不再使用 new Object()形式,可以根据用户的选择条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。

目录结构:

类图:核桃仁实例和碧根果实例是由SimpleFactory创建

实体类基类(snacks)

public abstract class Snacks {
    
    //商店名称
    private String name;

    //准备原材料
    public abstract void prepare();

    //打包盒
    public abstract void box();

    public void machining(){
        System.out.println(name + "加工生产;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

三只松鼠碧根果实体类(Pecan )

public class Pecan extends Snacks {
    @Override
    public void prepare() {
        System.out.println("碧根果准备原材料");
    }

    @Override
    public void box() {
        System.out.println("碧根果打包");
    }
}

三只松鼠核桃仁实体类(WalnutKernel )

public class WalnutKernel extends Snacks {
    @Override
    public void prepare() {
        System.out.println("核桃仁准备原材料");
    }

    @Override
    public void box() {
        System.out.println("核桃仁打包");
    }
}

工厂类(SimpleFactory)

简单工厂模式只是将需要经常修改的部分代码重新封装个类,在需要新增、删、改商店的时候就只修改这个类。这个做法有利也有弊,好处就是只修改这个类就可以,弊处是当商店有许多时,这个类容易变得臃肿。

这里的类型可以做成枚举类,在调用的时候也用枚举类。

public class SimpleFactory {

    public static Snacks getFactory( String store){
        Snacks snacks = null;
        switch (store){
            case "核桃仁":
                snacks = new WalnutKernel();
                snacks.setName("核桃仁的");
                break;
            case "碧根果":
                snacks = new Pecan();
                snacks.setName("碧根果的");
                break;
            default:
                System.out.println("无此产品");
                break;
        }
        return snacks;
    }
}

订单类(OrderSnacks)

public class OrderSnacks {

    public OrderSnacks(String store) {
        Snacks snacks = SimpleFactory.getFactory(store);
        if (null != snacks) {
            snacks.prepare();
            snacks.machining();
            snacks.box();
        }
    }
}
 

客户类(Client )

我们无需提供具体的子类类名,只需要提供一个字符串即可得到相应的实例对象。这样的话,当子类的类名更换或者增加子类时我们都无需修改客户端代码,只需要在简单工厂类上增加一个分支判断代码即可。

这就违反了“开闭原则”,对提供者拓展开放,对使用者修改关闭,在需要多加一个产品类时,拓展是好拓展,但需要修改工厂类,这就对使用者修改开放了。

public class Client {
    public static void main(String[] args) {
        new OrderSnacks("碧根果");
    }
}

结果:

工厂模式

由多个工厂维护自身产品。

目录结构

类图:产品类的实例都是由工厂创建

产品基类(Snacks)

public abstract class Snacks {

    //商店名称
    private String name;

    //准备原材料
    public abstract void prepare();

    //打包盒
    public abstract void box();

    public void machining(){
        System.out.println(name + "加工生产;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

百草味核桃仁实体类(BaiCaoFlavoWalnutKernel )

public class BaiCaoFlavoWalnutKernel extends Snacks {
    @Override
    public void prepare() {
        System.out.println("百草味核桃仁准备原材料");
    }

    @Override
    public void box() {
        System.out.println("百草味核桃仁打包");
    }
}

百草味碧根果实体类(BaiCaoFlavoPecan )

public class BaiCaoFlavoPecan extends Snacks {
    @Override
    public void prepare() {
        System.out.println("百草味碧根果准备原材料");
    }

    @Override
    public void box() {
        System.out.println("百草味碧根果打包");
    }
}

三只松鼠核桃仁实体类(ThreeSquirrelsWalnutKernel )

public class ThreeSquirrelsWalnutKernel extends Snacks {
    @Override
    public void prepare() {
        System.out.println("三只松鼠核桃仁准备原材料");
    }

    @Override
    public void box() {
        System.out.println("三只松鼠核桃仁打包");
    }
}

三只松鼠碧根果实体类(ThreeSquirrelsPecan )

public class ThreeSquirrelsPecan extends Snacks {
    @Override
    public void prepare() {
        System.out.println("三只松鼠碧根果准备原材料");
    }

    @Override
    public void box() {
        System.out.println("三只松鼠碧根果打包");
    }
}

百草味工厂(BaiCaoFlavo )

public class BaiCaoFlavo {

    public Snacks createdProduct(String store) {
       Snacks snacks = null;
        switch (store) {
            case "核桃仁":
                snacks = new BaiCaoFlavoWalnutKernel();
                snacks.setName("百草味核桃仁的");
                break;
            case "碧根果":
                snacks = new BaiCaoFlavoPecan();
                snacks.setName("百草味碧根果的");
                break;
            default:
                System.out.println("无此产品");
                return null;
        }
        snacks.prepare();
        snacks.machining();
        snacks.box();
        return snacks;
    }
}

三只松鼠工厂(ThreeSquirrels )

public class ThreeSquirrels {

    public Snacks createdProduct(String store) {
        Snacks snacks = null;
        switch (store) {
            case "核桃仁":
                snacks = new ThreeSquirrelsWalnutKernel();
                snacks.setName("三只松鼠核桃仁的");
                break;
            case "碧根果":
                snacks = new ThreeSquirrelsPecan();
                snacks.setName("三只松鼠碧根果的");
                break;
            default:
                System.out.println("无此产品");
                return null;
        }
        snacks.prepare();
        snacks.machining();
        snacks.box();
        return snacks;
    }
}

客户端(Client )

客户需要创建工厂,然后去调用工厂创建产品的方法。

public class Client {
    public static void main(String[] args) {
        //新建工厂
        BaiCaoFlavo store = new BaiCaoFlavo();
        //工厂创建产品
        store.createdProduct("碧根果");
    }
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值