工厂(Factory)模式

第四章 工厂(Factory)模式

1.除了使用new操作符之外,还有更多制造对象的方法.实例化这个活动不应该总是公开地进行,并且初始化经常造成"耦合"问题.

2.针对接口编程,而不是针对实现编程.但是,每当我们有new实例化一个类的时候,用的是实现,而不是接口.这就使得代码绑定具体类,导致代码更加脆弱,更缺乏弹性.

3.(封装变化)找出会变化的部分,将他们抽出来,与不会变化部分分离.工厂(Factory)模式就是应用封装变化原则将实例化具体类的代码从应用中抽离,或者封装起来,使它们不会干扰应用的其他部分.

4.工厂(Factory)模式将类实例化工作从客户端移到一个工厂类中,虽然看似只是从一个类移到另一个类,但是这样能达到代码复用目的,并且把具体实例化的过程,从客户的代码中删除.

5.静态工厂: 利用静态方法定义一个简单的工厂.
(缺点)不能通过继承来改变创建方法的行为.

6.简单工厂其实不是一个设计模式,反而比较像是一种编程习惯.不过,有些开发人员的确是把这种编程习惯误认为是"工厂模式".

7.在设计模式中,所谓的 "实现一个接口",并 "不一定" 表示 "写一个类,并利用implement关键词来实现某个Java接口" . "实现一个接口" 泛指 "实现某个超类型(可以是类或接口的某个方法)"

8.在工厂模式中,超类方法:orderPizza(),并不知道正在创建的比萨对象是哪一种.

9.在简单工厂中,所有具体类的实例化操作由一具体的类SimpleFactory对象来完成,而在工厂模式中,通过对超类PizzaStore做一些小转变,变成由一群子类来负责实例化.

10. abstract Product factoryMethod(String type)
①工厂方法(factoryMethod)用来处理对象的创建,并将这样的行为封闭在子类中.这样,客户程序中关于超类的代码就和子类对象创建代码解耦了.
②工厂方法是抽象的,所以依赖子类来处理对象的创建.即把决定权交由子类.
③工厂方法必须返回一个产品.超类中定义的方法,通常使用到工厂方法的返回值.
④工厂方法将客户(也就是超类中的代码,例如orderPizza())和实际创建具体产品的代码分隔开来.
⑤工厂方法可能需要参数(也可能不需要)来指定所要的产品.

11.超类从来不管细节.通过实例化正确的比萨类,子类会自行照料这一切.

12.所有工厂模式都用来封装对象的创建.工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的.

13.将一个orderPizza()方法和一个工厂方法联合起来,就可以成为一个 框架 .除此之外,工厂方法将生产知识封装进各个创建者,这样的做法,也可以被视为是一个 框架 .

14.(定义)工厂方法模式: 定义了一个创建对象的接口(实现某个超类型的方法,即工厂方法),但由子类决定要实例化的类是哪一个。工厂类把实例化推迟到子类.

15.(错误理解)常常有人说: 工厂方法让子类决定要实例化的类是哪一个.其实这样理解错误.工厂方法只是将实例化类的工作交由工厂方法来完成,而实际要用到哪个类还是由客户决定的.所谓的 "决定" ,并不是指模式允许子类本身在运行时做决定,而是指在编写创建者类(工厂类)时,不需要知道实际创建的产品是哪一个.选择了使用哪个子类,自然就决定了实际创建的产品是什么.

16.工厂类实现了所有操纵产品的方法,但不实现工厂方法(factoryMethod()方法).

17.当工厂方法模式中只有一个具体工厂类时(此时将会有不少其他的模式也可用),它 的存在依然很有用.他帮助我们将产品的 "实现" 从 "使用" 中解耦.如果增加产品或者改变产品的实现,工厂类并不会受到影响.

18.工厂方法模式(Factory Method Pattern)中具体工厂扩展自一个类(工厂类),此类有一个抽象方法(工厂方法).由每个工厂自行负责工厂方法的行为.而在简单工厂中,工厂是另一个由具体工厂类使用的对象.

19.工厂方法模式(Factory Method Pattern)中工厂类,工厂方法可以不必是抽象的,可以定义一个默认的工厂方法来产生某些具体的产品,这么一来,即使创建者没有任何子类,依然可以创建产品.

20.工厂方法通过传入参数的不同来实例化不同的具体工厂类.这种方式称为"参数化工厂方法".然而,工厂经常只产生一种对象,不需要参数化.参数有无是工厂模式的二种形式.

21.编程开发阶段,通过字符串传入参数化的类型,容易因为参数输入不正确而出现"运行时错误".编程开发期间应当注意这个问题.

22.简单工厂把全部的事情,在一个地方都处理完,将对旬的创建封装起来,然而工厂方法却是创建一个框架,让子类 "决定" 如何实现.简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品.

23.框架Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。

24.工厂带来的好处: 将创建对象的代码集中在一个对象或方法中,可以避免代码中的重复,并且更方便以后的维护.这也意味着客户在实例化对象时,只会依赖于接口,而不是具体类.这让代码更具有弹性,可以应对未来的扩展.

25.封装起创建对象的代码,就可以对抽象编码,将客户代码和真实的实现解耦.

26.设计原则六: 依赖倒置原则IoCP(Inversion of Control Principle)或依赖注入原则DIP(Dependency Injection Principle): 要依赖抽象,不要依赖具体类.这个原则说明了: 不能让高层组件依赖于低层组件,而且,不管高层或者低层组件,都应该依赖于抽象.所谓高层组件是由其他低层组件定义其行为的类.
依赖: 简单理解就是一个类A使用到类B,类B的变化会影响到类A.表现在代码层面,为类B作为参数被类A在某个方法中使用.

27.依赖倒置原则中的倒置指的是和一般OO设计思考方式完全相反.其中,低层组件和高层组件都依赖于高层的抽象.

28.三个指导方针,帮助避免在OO设计中违反依赖倒置原则:
①变量不可以持有具体类的引用.如果使用new,就会持有具体类的引用.可以改用工厂来避开这样的做法.
②不要让类派生自具体类.如果派生自具体类,你就会依赖具体类.请派生自一个抽象(接口或抽象类)
③不要覆盖基类中已实现的方法.如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象.基类中已实现的方法,应该由所有的子类共享.
完全遵守这些指导方针很难办到.在实际程序编写过程中,我们应当尽量达到依赖倒置原则,而不是随时都遵循这个原则.任何Java程序都有违反这些指导方针的地方.

29.在实际编程过程中,①如果有一个不像是会改变的类,那么在代码中直接实例化具体类(违反依赖倒置原则)也就没什么大碍.例如,因为String类型字符串不可能改变,所以编程时可直接实例化字符串对象.②如果有一个类可能改变,那么就可能采用一些好技巧(例如工厂方法)来封装改变.

30.如果每个工厂实例内都有某一种通用的"机制"需要实现,就可以把这个例子改写成抽象类.

31.通过传入各种不同的工厂,可以制作出各种不同的产品.但是客户代码始终保持不变.注意,让客户代码保持不变才是设计模式的目的.

32.抽象工厂模式(AbstractFactory):提供一个接口,用于创建相关或依赖对象的家庭,而不需要明确指定具体类.

33.抽象工厂允许客户使用接口来创建一组相关的产品,而不需要知道(或关心)实际产生的具体产品是什么.这样一来,客户就从具体的产品中被解耦.

34.抽象工厂的每个方法实际上看起来都像是工厂方法.每个方法都被声明成抽象,而子类的方法覆盖这些方法来创建某些对象.抽象工厂的方法经常以工厂方法的方式实现.抽象工厂的任务是定义一个负责创建一组产品的接口.这个接口内的每个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法.所以,在抽象工厂中利用工厂方法实现生产方法是相当自然的做法.

35.工厂方法和抽象工厂都是负责创建对象.不同的是,工厂方法模式用的是方法继承,而抽象工厂模式通过对象的组合.
①工厂方法创建对象,需要扩展自一个类,并覆盖它的工厂方法.整个工厂方法模式,只不过就是通过子类来创建对象.用这种做法,客户只需要知道他们所使用的抽象类型就可以了,而由子类来负责决定具体类型.
所以,换句话说道,工厂方法只负责将客户从具体类型中解耦.
②抽象工厂模式用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法.要想使用这个工厂,必须先实例化它,然后将它传入一些针对抽象类型所写的代码中.
所以,和工厂方法一样,抽象工厂也是把客户从所使用的实际具体产品中解耦.另一个优点: 把一群相关的产品集合起来.

36.①抽象工厂适用性: 当需要创建产品家庭和想让制造的相关产品集合起来时.
它可以把客户代码从所使用的实际具体产品中解耦.
②工厂方法适用性: 如果目前还不知道将来需要实例化哪些具体类时.
它可以把客户代码从需要实例化的具体类中解耦.
具体用法: 超类中定义(或声明)抽象工厂方法,子类继承超类并重写(或实现)工厂方法就可以了.

37.总结:
<1>OO原则: 1.多用组合,少用继承 2.针对接口编程,不针对实现编程 3.为交互对象之间的松耦合设计而努力 4.类应该对修改关闭,对扩展开放 5.依赖抽象而不是依赖具体类 6.封装变化
<2>OO模式: ①工厂方法模式(Factory Method Pattern):定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类.
②抽象工厂模式(Abstract Factory Pattern): 提供一个接口,用于创建相关或依赖对象的家庭,而不需要 明确指定具体类.
<3>所有的工厂都是用来封装对象的创建.
<4>①简单工厂,虽然不是真正的设计模式,但仍失为一个简单的方法,可以将客户程序从具体类解耦.
②工厂方法使用继承: 把对象的创建委托给子类,子类实现工厂方法来创建对象.
③抽象工厂使用对象组合: 对象的创建被实现在工厂接口所暴露出来的方法中.
<5>所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合.
<6>工厂方法允许类将实例化延迟到子类进行.
<7>抽象工厂创建相关的对象家族,而不需要依赖它们的具体类(其接口中声明工厂方法,交由子类决定实例化哪个类).
<8>依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象
<9>工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程.
Page Factory是Selenium WebDriver的一个扩展,它提供了一种用于管理页面对象的工厂模式。在测试过程,我们需要与页面交互,这意味着我们需要操作页面上的各种元素(如文本框、按钮、下拉列表等)。为了使测试代码更可维护、可读性更好,我们可以使用Page Factory来管理页面对象。 Page Factory使用注解的方式来初始化页面对象,这些对象可以直接通过测试类的成员变量访问。这使得代码更加简洁、易于维护。 下面是一个示例: ```java public class LoginPage { @FindBy(id = "username") private WebElement usernameInput; @FindBy(id = "password") private WebElement passwordInput; @FindBy(id = "loginButton") private WebElement loginButton; public void login(String username, String password) { usernameInput.sendKeys(username); passwordInput.sendKeys(password); loginButton.click(); } } ``` 在上面的代码,我们使用了`@FindBy`注解来初始化页面元素对象。这些对象可以直接通过类的成员变量来访问。 在测试代码,我们可以像下面这样使用LoginPage: ```java public class LoginTest { private WebDriver driver; private LoginPage loginPage; @BeforeTest public void setup() { driver = new ChromeDriver(); loginPage = PageFactory.initElements(driver, LoginPage.class); } @Test public void testLogin() { loginPage.login("username", "password"); } @AfterTest public void teardown() { driver.quit(); } } ``` 在上面的测试代码,我们使用了`PageFactory.initElements`方法来初始化LoginPage对象。这个方法会自动查找LoginPage使用`@FindBy`注解的成员变量,并将它们初始化为页面元素对象。 使用Page Factory可以使测试代码更加简洁、易于维护。它提供了一个优雅的方式来管理页面对象。如果你使用Selenium WebDriver进行自动化测试,建议你尝试使用Page Factory
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值