大家好,欢迎来到IT知识分享网。
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
目录
三、工厂方法(Factory Method)(优点在于横向扩展)
一、工厂模式的形态
工厂模式主要有以下几种形态:
- 简单工厂(Simple Factory)
- 工厂方法(Factory Method)
- 抽象工厂(Abstract Factory)
二、简单工厂(Simple Factory)
定义:专门定义一个类(第三方)来创建其他类实例(解耦,将客户端创建对象的操作解耦到外部第三方类),被创建的实例通常都具有共同的父类。 —用于没有产品族并且产品个数较少
eg:
首先定义一个抽象类:机器,可以用来生产电脑
然后定义多个具体产品类:产品流水线,每个流水线负责生产该品牌产品
最后定义一个工厂类:工厂类中有许多不同流水线,其中可以生产多品牌电脑
用户想要的时候,只用在客户端输入想要的产品,与此对应的产品就会从工厂中生产,用户不必知道是如何生产的
组成: a.一个抽象类 interface factory
b.N个具体产品类 class MacBook implements factory{} class Aline implements factory{} ……
c.一个工厂类 class RealFactory{ public static factory produce(String pro){…} }
//简单工厂模式 //定义一个抽象类,假设这是一个生产电脑的机器 interface factory{ void create(); } //---------------------- 多个具体产品类 ------------------------------------- //定义一个产品类,使用此机器生产品牌电脑 class MacBook implements factory{ @Override public void create() { System.out.println("生产一个MacBook电脑"); } } class Acer implements factory{ @Override public void create() { System.out.println("生产一个Acer电脑"); } } class Aline implements factory{ @Override public void create() { System.out.println("生产一个Aline电脑"); } } //--------------------------------------------------------------- //定义一个工厂类,拥有几条流水线工程来生产不同品牌的电脑 class RealFactory{ public static factory produce(String name) { if (name.equals("MacBook")) { return new MacBook(); } else if (name.equals("Acer")) { return new Acer(); } else if (name.equals("Aline")) { return new Aline(); } System.out.println("此工厂不生产"+name); return null; } } public class SimpleFactory { public static void main(String[] args) { RealFactory fac = new RealFactory(); System.out.println("请输入你想要的电脑:"); Scanner in = new Scanner(System.in); String name = in.next(); fac.produce(name).create(); } }
结果:
正确输入:
错误输入:
由上面的代码可以看出,简单工厂的核心就是一个RealFactory类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把定单给他,就能得到我们想要的产品。这使用起来似乎非常方便。
但是,实际上,这个RealFactory有很多的局限。首先,我们每次想要增加一种新产品的时候,都必须修改RealFactory的原代码,这显然违反了开闭原则。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这非常不符合我们的编码原则。还有就是,整个系统都严重依赖RealFactory类,如果RealFactory类出问题,系统就进入不能工作的状态,这也是最为致命的一点….
所以简单工厂只适合于产品对象较少,且产品固定的需求,对于产品变化无常的需求来说显然不合适
以上的不足将在工厂模式的另外两种状态中得到解决。
三、工厂方法(Factory Method)(优点在于横向扩展)
上面的代码告诉我们,简单工厂是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。
定义:工厂方法定义一个用来创建对象的接口,用多态来削弱了工厂类的职能,让子类决定实例化哪一个工厂。
eg:
首先定义一个抽象类:机器,可以用来生产电脑
然后定义多个具体产品类:产品流水线,每个流水线负责生产该品牌产品
然后定义一个抽象工厂,工厂可以流水线生产电脑
最后定义多个工厂类:每个工厂可以生产自己品牌的电脑
用户想要的时候,只用找到对应品牌的工厂发送请求,与此对应的产品就会从工厂中生产,每个品牌工厂自己管理自己流水线电脑,其他的工厂产品出问题或者倒闭了都和自家的没关系:)
组成: a. 一个抽象产品类 interface Computre
b.多个具体产品类 class MacBook implements Computre 。。。
c.一个抽象工厂 interface ComputerFactory
d.多个具体工厂(每个产品族对应一个具体工厂) class msFactory implements ComputerFactory
interface Computre{ void create(); } //---------------------- 多个具体产品类 ------------------------------------- class MacBook implements Computre{ @Override public void create() { System.out.println("生产一个MacBook电脑"); } } class Aline implements Computre{ @Override public void create() {System.out.println("生产一个外星人电脑");} } class Acer implements Computre{ @Override public void create() {System.out.println("生产一个Acer电脑"); } } //------------------------------------------------------------------------------ interface ComputerFactory{ Computre createComputer(); } //---------------------- 多个具体工厂 ------------------------------------- //弘基电脑工厂 class msFactory implements ComputerFactory{ @Override public Computre createComputer() { return new Acer(); } } //苹果产品工厂 class AppleFactory implements ComputerFactory{ @Override public Computre createComputer() { return new MacBook(); } } //微软产品工厂 class AcerFactory implements ComputerFactory{ @Override public Computre createComputer() { return new Aline(); } } //------------------------------------------------------------------------------ public class FactoryMethod{ public static void main(String[] args) throws InterruptedException { ComputerFactory computerFactory = new AppleFactory(); Computre computre = computerFactory.createComputer(); computre.create(); } }
结果:
从上面创建产品的栗子可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。
但是工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,苹果工厂除了生产电脑,还生产手机产品,这样一来电脑和手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又会有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这在现实中显然是不可能发生的。
四、抽象工厂(Factory Method)
抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。
特点:提供一个创建一系列相关或相互依赖对象的接口(抽象工厂、多条产品线),而无需指定他们具体的类。
抽象工厂和工厂方法的模式基本一样,区别在于,工厂方法是生产一个具体的产品,而抽象工厂可以用来生产一组相同,有相对关系的产品;重点在于一组,一批,一系列。
举个例子,假如生产华为手机,小米手机有很多系列,华为荣耀系列、华为P系列、华为Nova系列等;假如Nova3生产需要的配件有麒麟970的处理器,6.3英寸屏幕,而荣耀10只需要麒麟940的处理器和5.84寸的屏幕就可以了;用抽象工厂来实现:
//抽象工厂 //CPU接口 interface Cpu { void run(); class Cpu940 implements Cpu { @Override public void run() { System.out.println("我的CPU是麒麟940呦"); } } class Cpu970 implements Cpu { @Override public void run() { System.out.println("我的CPU是麒麟970"); } } } //屏幕接口 interface Screen { void size(); class Screen5 implements Screen { @Override public void size() { System.out.println("我的屏幕是5寸"); } } class Screen6 implements Screen { @Override public void size() { System.out.println("我的屏幕是6寸"); } } } //工厂接口 interface PhoneFactory { Cpu getCpu();//使用的cpu Screen getScreen();//使用的屏幕 } //--------------------------------具体实现类--------------------------- //Nova3 class Nova3Factory implements PhoneFactory { @Override public Cpu getCpu() { return new Cpu.Cpu970(); } @Override public Screen getScreen() { return new Screen.Screen6(); } } //荣耀10 class HonorFactory implements PhoneFactory { @Override public Cpu getCpu() { return new Cpu.Cpu940(); } @Override public Screen getScreen() { return new Screen.Screen5(); } } //------------------------------------------------------------------- public class AbstFactory { public static void main(String[] args) { PhoneFactory phone = new Nova3Factory(); phone.getCpu().run(); phone.getScreen().size(); } }
从以上的例子可以看出,抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展;
五、适用场景:
无论是简单工厂模式,工厂方法模式还是抽象工厂模式,它们都具有类似的特性,适用场景也十分类似。
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。使用工厂方法后,调用端的耦合度大大降低了。并且对于工厂来说,是可以扩展的,以后如果想组装其他的产品,只需要再增加一个工厂类的实现就可以。无论是灵活性还是稳定性都得到了极大的提高。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/151896.html