哇塞!这么全的工厂模式你见过吗
2020/7/3 17:26:55
本文主要是介绍哇塞!这么全的工厂模式你见过吗,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
设计模式二--工厂模式
举例:
女娲采集黄土捏成人的形状,然后放到八卦炉中烧制,然后放到土地上生长,但是意外随时都会发生。
- 第一次烤人,感觉应该熟了,往地上一放,哇,没烤熟,白人诞生了。
- 第二次烤人,上一次没有烤熟,这次多烤一会,放到世间一看,哇,熟过头了,于是黑人诞生了。
- 第三次烤人,一边烧制一遍看,知道表皮发黄,嘿,刚刚好,于是黄种人诞生了。
思考:
- 在面向对象编程的思想中,万物皆对象。于是我们抽象出具体的三个对象。
- 女娲,八卦炉,三种不同肤色的人。
- 女娲可以用场景类Client来表示,八卦炉可以用工厂来表示,三个不同肤色的人,他们都是同一个接口下面的不同实现类。 于是我们生成类图。
- AbstarctHummanFactory是一个抽象类,HumanFactoruy是一个实现类,完成具体的任务,创建人类。Human是人类- 总称,三个人种是其实现类,Nawa是一个场景,负责模拟这个场景,发起任务。
人类接口
/** * @atuhor sha1024 */ public interface Human { void getTalk(); void getColor(); } 复制代码
白人人类
/** * @atuhor sha1024 */ public class WhiteHuman implements Human{ @Override public void getTalk() { System.out.println("我是一个白人"); } @Override public void getColor() { System.out.println("我的皮肤是白色的"); } } 复制代码
黄色人种
/** * @atuhor sha1024 */ public class YellowHuman implements Human{ @Override public void getTalk() { System.out.println("黄种人说话最好听"); } @Override public void getColor() { System.out.println("我的皮肤是黄色的"); } } 复制代码
黑色人种
/** * @atuhor sha1024 */ public class BlackHuman implements Human{ @Override public void getTalk() { System.out.println("黑人说话听不懂"); } @Override public void getColor() { System.out.println("我的皮肤是黑色的"); } } 复制代码
定义一个抽象工厂,定义了一个泛型实现了Human
/** * @atuhor sha1024 */ public abstract class AbstarctHummanFactory { public abstract <T extends Human> T createHuman(Class<T> c); } 定义了一个人类工厂实现抽象人类工厂 public class HummanFactory extends AbstarctHummanFactory { @Override public <T extends Human> T createHuman(Class<T> c) { //定义一个人种 Human human = null; try{ human = (T)Class.forName(c.getName()).newInstance(); }catch (Exception e){ throw new RuntimeException("定义人种错误"); } return (T)human; } } 复制代码
女娲类,实现具体的场景
public static void main(String[] args) { AbstarctHummanFactory hummanFactory = new HummanFactory(); Human whiteHuman = hummanFactory.createHuman(WhiteHuman.class); whiteHuman.getColor(); whiteHuman.getTalk(); Human blackHuman = hummanFactory.createHuman(BlackHuman.class); blackHuman.getTalk(); blackHuman.getColor(); Human yellowHuman = hummanFactory.createHuman(YellowHuman.class); yellowHuman.getColor(); yellowHuman.getTalk(); SpringApplication.run(FactoryApplication.class, args); } 复制代码
执行结果
工厂方法模式的定义
- 定义一个用于创建对象的接口,让子类来决定实例化哪一个。工厂方法使一个类的实例化延迟到其子类。
在工厂模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreateCreator完成的。 具体的产品类可以有多个,都继承抽象产品类
/** * 抽象产品类 * @atuhor sha1024 */ public abstract class Product { //产品类的公共方法 public void method1(){ System.out.println("我是抽象工厂方法1"); } /** * 抽象方法 */ public abstract void method2(); } 复制代码
产品类1
/** * @atuhor sha1024 */ public class ConcreateProduct1 extends Product { @Override public void method2() { /** * 具体业务逻辑 */ } } 复制代码
产品类2
/** * @atuhor sha1024 */ public class ConcreateProduct2 extends Product { @Override public void method2() { /** * 业务逻辑 */ } } 复制代码
抽象工厂
/** * @atuhor sha1024 */ public abstract class Creator { /** * 创建一个产品对象,其输入任何参数类型都可以自行设置 * 通常为String,Enum,Class,也可以为空 */ public abstract <T extends Product> T createProduct(Class<T> c); } 复制代码
具体如何产生一个产品对 对象是由具体的工厂实现类来决定的
/** * 通过发射获取到实例 * @atuhor sha1024 */ public class ConcreateCreator extends Creator{ @Override public <T extends Product> T createProduct(Class<T> c) { Product product = null; try{ product = (T)Class.forName(c.getName()).newInstance(); }catch (Exception e){ throw new RuntimeException(e.getMessage()); } return (T)product; } } 复制代码
场景类
/** * @atuhor sha1024 */ public class Client { public static void main(String[] args){ Creator creator = new ConcreateCreator(); Product product = creator.createProduct(ConcreateProduct1.class); /** * 业务逻辑 */ product.method2(); } } 复制代码
工厂模式的优点:
- 良好的封装性,代码结果清晰。
- 工厂方法模式的扩展性非常好。
- 屏蔽产品类,产品类如何变化,调用者不用关心,它只需要关心产品的接口。更好的实现了解耦合。
工厂方法模式使用场景
- 工厂方法是new一个对象的 替代品,所以在所有需要生成对象的地方都可以使用,但是要考虑是否要增加一个产品类来增加代码的复杂性。
- 需要灵活的可扩展的框架时,可以考虑采用工厂方法模式。
工厂模式的扩展
缩小为简单工厂模式
上图中我们去掉了AbstarctHummanFactory抽象人类工厂,同时把createHuman改为静态类型。
/** * @atuhor sha1024 */ public class NvWa { public static void main(String[] args){ Human human = HummanFactory2.createHuman(YellowHuman.class); Human human2 = HummanFactory2.createHuman(BlackHuman.class); } } 复制代码
运行结果没用发生变化,但是我们的类图变得更加简单了,因为简单所以我们称为简单工厂模式
升级为多个工厂模式
当我们在做一个复杂项目的时候,经常会遇到初始化一个对象很费力的情况,所有产品都放到一个工厂方法中进行初始化会使代吗结构不清晰。例如:一个产品类有5个具体实现类,每个实现类的初始化方法都不相同,如果写在工厂中,会导致该方法巨大无比。 考虑到要结构清晰,我们就为每个产品定义一个创造者,然后由调用者去选择与哪个工厂方法关联。定义一个抽象工厂
public abstract class AbstarctHummanFactory { public abstract Human createHuman(); } 复制代码
黑人人种创建工厂
public class BlackHummanFactory extends AbstarctHummanFactory { @Override public Human createHuman() { return new BlackHuman(); } } 复制代码
黄色人种创建工厂
public class YellowHummanFactory extends AbstarctHummanFactory { @Override public Human createHuman() { return new YellowHuman(); } } 复制代码
场景类
public static void main(String[] args){ Human yellowHuman = (new YellowHummanFactory()).createHuman(); yellowHuman.getTalk(); yellowHuman.getColor(); Human blackHuman = (new BlackHummanFactory()).createHuman(); blackHuman.getTalk(); blackHuman.getColor(); } 复制代码
运行结果还是相同的,每一个产品类都对应了一个创建类好处就是创建类职责清晰,而且结构简单,但是给可扩展性和维护性带来了一定的影响。
当然,在复杂的应用场景中一般采用多工厂模式,然后增加一个协调类,避免调用者和各个子工厂交流,对高层模块提供统一调用api。
替代单例模式
Singleton定义了一个private 的无参构造函数,目的是不允许通过new 的方式创建一个对象public class Singleton { private Singleton(){} public void doSomeThing(){ //业务逻辑 } } 复制代码
单例类,Singleton保证不能通过正常情况下建立一个对象,只能通过反射方式创建
public class SingletonFactory { private static Singleton singleton; static { try{ Class c1 = Class.forName(Singleton.class.getName()); //获取无参构造函数 Constructor constructor = c1.getDeclaredConstructor(); //设置无参是可访问的 constructor.setAccessible(true); //产生一个实例对象 singleton = (Singleton) constructor.newInstance(); }catch(Exception e){ } } public static Singleton getSingleton(){ return singleton; } 复制代码
通过获得类构造器,然后设置访问权限,生成一个对象,然后提供外部访问,保证内部中的对象唯一。当然,其他的类也能通过反射的方式获得一个单例对象。
延迟初始化
ProductFactory负责产品类对象的创建,并通过prMap创建一个缓存,对需要被重用的对象保留public class ProductFactory { private static final Map<String,Product> prMap = new HashMap<>(); public static synchronized Product createProduct(String type) throws Exception{ Product product = null; //判断缓存中是否有这个对象 if(prMap.containsKey(type)){ product = prMap.get(type); }else{ if(type.equals("Product1")){ product = new ConcreateProduct1(); }else{ product = new ConcreateProduct2(); } //同时缓存数据到prMap中 prMap.put(type,product); } return product; } } 复制代码
通过定义一个Map容器,容纳所有对象,如果Map容器中已经有的对象,则直接取出;如果没用,则根据需要的类型产生一个对象并放入到Map容器中。
这篇关于哇塞!这么全的工厂模式你见过吗的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-06小米11i印度快充版ROM合集:极致体验,超越期待
- 2024-10-06【ROM下载】小米11i 5G 印度版系统, 疾速跃迁,定义新速度
- 2024-10-06【ROM下载】小米 11 青春活力版,青春无极限,活力全开
- 2024-10-05小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求