今天学习的是创造型设计模式之一 '工厂模式',我们经常讲的可分为三类
1.简单工厂
2.工厂方法
3.抽象工厂
如果现在有一个需求,上传图片到客户配置的服务器地址。可能存在多种类型服务器如(腾讯云,阿里云,百度云)
一.简单工厂
/** * @description: Api服务service * @author: ZhuCJ * @date: 2020-09-01 13:07
*/ public interface ApiService { /** * 上传图片 * @return */ Boolean uploadImg(); }
/** * @description: 百度服务API * @author: ZhuCJ 80004071 * @date: 2020-09-01 13:08 */ public class BaiduServiceImpl implements ApiService{ @Override public Boolean uploadImg() { System.out.println("百度API服务---->执行上传图片至百度云"); return true; } } /** * @description: 腾讯服务API * @author: ZhuCJ 80004071 * @date: 2020-09-01 13:08 */ public class TencentApiServiceImpl implements ApiService{ @Override public Boolean uploadImg() { System.out.println("腾讯API服务---->执行上传图片到腾讯云服务器"); return true; } } /** * @description: 简单工厂模型 * @author: ZhuCJ 80004071 * @date: 2020-09-01 13:03 */ public class SimplenessFactory { public static ApiService build(int i){ ApiService service = null; switch (i){ case 1: service = new TencentApiServiceImpl(); break; case 2: service = new BaiduServiceImpl(); break; default: break; } return service; } }
/** * @description: 测试 * @author: ZhuCJ 80004071 * @date: 2020-09-01 13:14 */ public class SimplenessMain { public static void main(String[] args) { int type = 1; /** 初学者创建对象方法*/ if (type == 1){ TencentApiServiceImpl tencentApiService = new TencentApiServiceImpl(); tencentApiService.uploadImg(); }else if (type == 2){ BaiduServiceImpl baiduService = new BaiduServiceImpl(); baiduService.uploadImg(); } /** 利用简单工厂创建对象 */ ApiService build = SimplenessFactory.build(type); build.uploadImg(); } }
总结:
new对象方式:
1.代码不美观,还需要根据逻辑来判断
2.不利于扩展和维护(如代码逻辑发生变动,需要删除代码重新new一个新的对象
简单工厂:
优点:1.解耦 添加新的对象,只需要找工厂类中添加即可,即也不需要关注业务逻辑;2.帮助封装,使面向接口编程;
缺点:1.不方便子工厂的扩展
二.工厂方法
/** * @description: 水果抽象工厂 * @author: ZhuCJ * @date: 2020-09-01 17:05 */ public abstract class FruitsAbstractFactory { /** * 创建水果 * @return */ public Fruits createFruits(){ return null; } }
/** * @description: * @author: ZhuCJ * @date: 2020-08-19 15:38 */ public class BananaFactory extends FruitsAbstractFactory { @Override public Fruits createFruits(){ return new Banana("香蕉","黄色"); } } /** * @description: * @author: ZhuCJ * @date: 2020-09-01 17:08 */ public class AppleFactory extends FruitsAbstractFactory { @Override public Fruits createFruits(){ return new Apple("苹果","红色"); } } /** * @description: * @author: ZhuCJ * @date: 2020-08-19 15:38 */ public class Apple extends Fruits { public Apple(String name,String cooler) { super.name = name; super.cooler = cooler; } } /** * @description: * @author: ZhuCJ * @date: 2020-08-19 15:38 */ public class Banana extends Fruits { public Banana(String name,String cooler){ super.name = name; super.cooler = cooler; } } /** * @description: 水果 * @author: ZhuCJ */ @Data @ToString @AllArgsConstructor @NoArgsConstructor @Builder public class Fruits { String name; String cooler; public void desc(){ System.out.println("我是:"+name+" 颜色是:"+cooler); } }
/** * @description: * @author: ZhuCJ * @date: 2020-09-01 17:22 */ public class MethodFactoryMain { public static void main(String[] args) { FruitsAbstractFactory appleFruitsFactory = new AppleFactory(); appleFruitsFactory.createFruits().desc(); FruitsAbstractFactory bananaFruitsFactory = new BananaFactory(); bananaFruitsFactory.createFruits().desc(); } }
总结:
工厂方法优势:
1.满足JAVA的开闭原则,即如果需要新增加产品,只需要简单继承即可
2.每一种工厂只负责生产一种产品,保证单独处理业务逻辑,减少了简单工厂中switch判断
缺点:
1.只能创建单一的产品
2.每新增加产品,都需要继承父类 增加系统复杂性
三.抽象工厂模式
/** * @description: 抽象工厂模式 * @author: ZhuCJ * @date: 2020-08-19 14:30 */ public abstract class AbstractFactory { /** * ****利用抽象工厂创建产品一组*********** */ /** * 创建水果产品线 * @return */ public AbstractFruits buildFruits(){ return null; } /** * 创建交通工具产品线 * @return */ public AbstractMedia buildMedia(){ return null; } /** * 创建电影 * @return */ public AbstractMovie buildMovie(){ return null; } }
/** * @description: 工厂一 * @author: ZhuCJ * @date: 2020-08-19 14:30 */ public class AbstractFactoryImplOne extends AbstractFactory { /** * =========工厂一 创建一个香蕉 和火车 和 老人与海的 工厂 */ /** * 创建香蕉产品 * @return */ @Override public AbstractFruits buildFruits(){ return new Banana("小香蕉"); } /** * 创建交通工具产品线 * @return */ @Override public AbstractMedia buildMedia(){ return new Train("T95号列车"); } /** * 创建交通工具产品线 * @return */ @Override public AbstractMovie buildMovie(){ return new OldMenAndSea(new Date(),"一部英勇的电影"); } } /** * @description: 水果抽象类 * @author: ZhuCJ * @date: 2020-08-19 16:14 */ @Data public abstract class AbstractFruits { String name; public AbstractFruits(String name) { this.name = name; } public AbstractFruits() { } } /** * @description: * @author: ZhuCJ * @date: 2020-08-19 15:38 */ public class Banana extends AbstractFruits implements Fruits { public Banana(String name){ super(name); } @Override public String getName() { return super.name; } @Override public void function() { } public void colour() { System.out.println(super.name+"颜色一般是黄色的"); } } /** * @description: 交通工具抽象类 * @author: ZhuCJ * @date: 2020-08-19 16:14 */ @Data public abstract class AbstractMedia { protected String name; public AbstractMedia(String name) { this.name = name; } } /** * @description: * @author: ZhuCJ * @date: 2020-08-19 15:38 */ public class Train extends AbstractMedia { public Train(String name) { super(name); } public String getName() { return super.name; } public void Function() { System.out.println(name+"承载着客人,穿行在铁轨上....."); } } /** * @description: 电影抽象类 * @author: ZhuCJ * @date: 2020-08-19 16:14 */ @Data public abstract class AbstractMovie { protected Date releaseDate; public AbstractMovie(Date releaseDate) { this.releaseDate = releaseDate; } } /** * @description: 老人与海 * @author: ZhuCJ * @date: 2020-08-21 13:21 */ public class OldMenAndSea extends AbstractMovie implements Movie { public OldMenAndSea(Date releaseDate) { super(releaseDate); } private String desc; public OldMenAndSea(Date releaseDate, String desc) { super(releaseDate); this.desc = desc; } public String introduce(){ return "老人与海"+ "上映时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(super.releaseDate)+" "+this.desc; } }
/** * @description: 抽象工厂 生产产品族 * @author: ZhuCJ 80004071 * @date: 2020-09-01 17:55 */ public class AbstractFactoryMain { public static void main(String[] args) { AbstractFactory factoryOne = new AbstractFactoryImplOne(); AbstractFruits abstractFruits = factoryOne.buildFruits(); System.out.println("创建水果---->"+abstractFruits.getName()); AbstractMedia abstractMedia = factoryOne.buildMedia(); System.out.println("创建交通工具---->"+abstractMedia.getName()); AbstractMovie abstractMovie = factoryOne.buildMovie(); System.out.println("创建的电影,上映时间----->"+abstractMovie.getReleaseDate()); } }
总结:抽象工厂解决工厂方法的单一产品线,支持生产产品一组。