简单工厂、工厂方法、抽象工厂简单总结

 作为一个程序员,设计模式必须掌握,不管是日常开发,还是面试都会涉及到。我对设计模式的理解有时候只停留在了理论概念上,实战项目总感觉写不出来,代码不够优雅,所以,从今天开始,一天学习一个设计模式,并把相似的容易混淆的设计模式做出对比,加深对设计模式的理解。

之前看设计模式,总是不去看UML,我发现,这个东西才是真正能看懂掌握设计模式的根基,就好比一剂良药,需要有个药引子才能发挥出药效,必须先能看懂UML再学习设计模式,这样会事半功倍。

1、简单工厂模式(后续都以生产冰淇淋为例子

UML,图上标注的序号,是类创建的步骤,我感觉这么写,能好理解一点

第一次,我先把每一个步骤都描述一下

  1. 创建接口 IceCreamService,定义方法 createIceCream(params)
  2. 创建2个实现类,AppleIceCreamServiceImpl、BananaIceCreamServiceImpl
  3. 创建工厂类 IceCreamFactory(params) ,定义方法getIceCreamService(params) 根据入参,返回需要生产的冰淇淋产品

下面是代码演示:

/**
 * 1、冰淇淋接口
 */
public interface IiceCream {
    void createIceCream();
}
/**
 * 2、苹果冰淇淋实现类
 */
public class AppleIceCream implements IiceCream {
    @Override
    public void createIceCream() {
        System.out.println("苹果冰淇淋");
    }
}
/**
 * 3、香蕉冰淇淋实现类
 */
public class BananaIceCreamServiceImpl implements IceCreamService{
    @Override
    public void createIceCream() {
        System.out.println("香蕉冰淇淋");
    }
}
/**
 * 4、冰淇淋工厂类
 */
public class IceCreamFactory {

    public IiceCream getIceCream(String params) {
        switch (params) {
            case "apple":
                return new AppleIceCream();
            case "banana":
                return new BananaIceCream();
            default:
                return null;
        }
    }

    public static void main(String[] args) {
        IceCreamFactory icf = new IceCreamFactory();
        // 生产苹果冰淇淋
        icf.getIceCream("apple").createIceCream();
        // 生产香蕉冰淇淋
        icf.getIceCream("banana").createIceCream();
    }
}

好了,简单工厂就完成了,很简单

2、工厂方法模式

上面的简单工厂方法有个弊端,如果要再新加别的冰淇淋,必须要去修改工厂类,这违反了设计原则-开闭原则

怎么规避这个弊端呢?工厂方法模式闪亮登场

UML

代码演示:

/**
 * 1、冰淇淋接口
 */
public interface IiceCream {
    void createIceCream();
}
/**
 * 2、苹果冰淇淋实现类
 */
public class AppleIceCream implements IiceCream {
    @Override
    public void createIceCream() {
        System.out.println("苹果冰淇淋");
    }
}
/**
 * 3、香蕉冰淇淋实现类
 */
public class BananaIceCream implements IiceCream {
    @Override
    public void createIceCream() {
        System.out.println("香蕉冰淇淋");
    }
}
/**
 * 4、冰淇淋工厂接口
 */
public interface IiceCreamFactory {
    IiceCream getIceCream();
}
/**
 *  5、苹果冰淇淋工厂实现类
 */
public class AppleFactory implements IiceCreamFactory {
    @Override
    public IiceCream getIceCream() {
        return new AppleIceCream();
    }
}
/**
 *  6、香蕉冰淇淋工厂实现类
 */
public class BananaFactory implements IiceCreamFactory {
    @Override
    public IiceCream getIceCream() {
        return new BananaIceCream();
    }
}
/**
 * 生产冰淇淋
 */
public class CreateIceCream {
    public static void main(String[] args) {
        // 苹果冰淇淋工厂
        IiceCreamFactory appleFactory = new AppleFactory();
        // 生产冰淇淋
        appleFactory.getIceCream().createIceCream();
        // 香蕉冰淇淋工厂
        IiceCreamFactory bananaFactory = new BananaFactory();
        // 生产冰淇淋
        bananaFactory.getIceCream().createIceCream();
    }
}

工厂方法模式完成,如果再新增一个橘子冰淇淋,分别创建一个工厂实现类,和冰淇淋实现类即可

3、抽象工厂模式

工厂方法模式已经可以完成大部分的需求,但是突然产品又提出了一个需求,现在不仅要生产冰淇淋,还要生产饮料,这时候,工厂方法模式可能有点扛不住了,因为工厂方法模式一个工厂只能生成一种产品。这时候抽象工厂模式炫丽登场

UML,是根据我自己的理解画的,跟网上大神的图不太一样,如有不正确的地方,大家指正,不过我觉得这么画更好理解

在画这个UML的时候,纠结了一会,从简单工厂到工厂方法,很容易理解,但是从工厂方法到抽象工厂,总感觉有点别扭。

:工厂方法到抽象工厂,正常的思路是,就是把冰淇淋工厂(IceCreamFactory)改造成,可以生产饮料不就行了?但是从实际想一下,真的有个冰淇淋工厂,那这个厂子里面的设备肯定不支持生产饮料的,两个完全不同的食品。

所以,如果想要生产冰淇淋,又要生产饮料,那你就不能再用冰淇淋工厂了,要用一个更大点的工厂,里面融合了生产冰淇淋和饮料的设备,可以同时生产这2种产品,比如说蒙牛,伊利这种大工厂

代码演示:

/**
 * 1、冰淇淋接口
 */
public interface IceCream {
    void createIceCream();
}
/**
 * 2、苹果冰淇淋
 */
public class AppleIceCream implements IceCream {
    @Override
    public void createIceCream() {
        System.out.println("苹果冰淇淋 ");
    }
}
/**
 * 3、香蕉冰淇淋
 */
public class BananaIceCream implements IceCream {
    @Override
    public void createIceCream() {
        System.out.println("香蕉冰淇淋 ");
    }
}
/**
 * 4、饮料接口
 */
public interface Drinks {
    void createDrinks();
}
/**
 * 5、苹果饮料
 */
public class AppleDrinks implements Drinks {
    @Override
    public void createDrinks() {
        System.out.println("苹果饮料");
    }
}
/**
 * 6、香蕉饮料
 */
public class BananaDrinks implements Drinks {
    @Override
    public void createDrinks() {
        System.out.println("香蕉饮料");
    }
}
/**
 * 7、抽象工厂接口,生产冰淇淋和饮料
 */
public interface AbstractFactory {
    // 冰淇淋
    IceCream createIceCream(String choice);
    // 饮料
    Drinks createDrinks(String choice);
}
/**
 * 8、蒙牛工厂
 */
public class MengNiuFactory implements AbstractFactory {
    @Override
    public IceCream createIceCream(String choice) {
        switch (choice) {
            case "banana":
                return new BananaIceCream();
            case "apple":
                return new AppleIceCream();
            default:
                return null;
        }
    }
    @Override
    public Drinks createDrinks(String choice) {
        switch (choice) {
            case "banana":
                return new BananaDrinks();
            case "apple":
                return new AppleDrinks();
            default:
                return null;
        }
    }
}
/**
 * 9、伊利工厂
 */
public class YiLiFactory implements AbstractFactory {
    @Override
    public IceCream createIceCream(String choice) {
        switch (choice) {
            case "banana":
                return new BananaIceCream();
            case "apple":
                return new AppleIceCream();
            default:
                return null;
        }
    }

    @Override
    public Drinks createDrinks(String choice) {
        switch (choice) {
            case "banana":
                return new BananaDrinks();
            case "apple":
                return new AppleDrinks();
            default:
                return null;
        }
    }
}
/**
 * 制造产品
 */
public class MakeProduct {
    public static void main(String[] args) {
        AbstractFactory yiLi = new YiLiFactory();
        System.out.println("伊利工厂生产");
        yiLi.createIceCream("apple").createIceCream();
        yiLi.createDrinks("banana").createDrinks();

        AbstractFactory mengNiu = new MengNiuFactory();
        System.out.println("蒙牛工厂生产");
        mengNiu.createIceCream("apple").createIceCream();
        mengNiu.createDrinks("banana").createDrinks();
    }
}

在实际的项目中,要根据需求选择合适的设计模式,但凡你用了一些设计模式,别人再看到你写的代码,都会对你高看一眼,我就这么觉得,看到别人把设计模式实战到项目中,就会觉得这个人厉害,内功深厚。

再补充一点,看了一些关于设计模式的书,解决了我的一个误区,设计模式并不是用得越多,或者说用法越复杂就越好,设计模式的初衷就是简化我们开发过程中遇到的一些困难,就好比上面的三种工厂模式,并不是说抽象工厂模式(复杂度高)最好,合适的场景,用适合的设计模式,才最好

所以,不能为了设计模式而设计模式,用的时候需要思考为什么我要用这个设计模式,用了之后会给我们的代码带来什么好处,都是要思考的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值