设计模式之:简单工厂模式。
个人印象笔记地址:https://app.yinxiang.com/fx/a45a73de-b62f-4083-bd3e-4c0c68ce4548

-
创建 抽象产品类 & 定义具体产品的公共接口;
-
创建 具体产品类(继承抽象产品类) & 定义生产的具体产品;
-
创建 工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
-
外界通过调用 工厂类的静态方法, 传入不同参数从而创建不同 具体产品类的实例
步骤1. 创建抽象产品类,定义具体产品的公共接口
abstract class Product{//抽象产品类
public abstract void Show();//抽象方法
}
步骤2. 创建具体产品类(继承抽象产品类),定义生产的具体产品
class ProductA extends Product{
///定义具体产品类A
@Override
public void Show() {
System.out.println("生产出了产品A");//重写覆盖原有show()方法
}}
class ProductB extends Product{//
//定义具体产品类B
@Override
public void Show() {
System.out.println("生产出了产品C");重写覆盖原有show()方法
}}
class ProductC extends Product{
//具体产品类C
@Override
public void Show() {
System.out.println("生产出了产品C");
}}
步骤3. 创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例。静态方法的调用:可以直接类名.方法
class Factory {
public static Product Manufacture(String ProductName){//带参数的工厂类
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
switch (ProductName){
case "A":
return new ProductA();
case "B":
return new ProductB();
case "C":
return new ProductC();
default:
return null;
}
}
}
步骤4. 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
//工厂产品生产流程
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();
不用实例化具体的产品类
//客户要产品A
try {//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.Manufacture("A").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品B
try {
mFactory.Manufacture("B").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品C
try {
mFactory.Manufacture("C").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品D
try {
mFactory.Manufacture("D").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
}
}
结果输出:
5. 优点
-
将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
-
把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。
6. 缺点
-
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
-
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
-
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构
设计模式之:工厂模式。

2. 使用步骤
abstract class Factory{
public abstract Product Manufacture();
}
步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
abstract class Product{
public abstract void Show();
}
步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
class ProductA extends Product{
//具体产品A类
@Override
public void Show() {
System.out.println("生产出了产品A");
}
}
class ProductB extends Product{
//具体产品B类
@Override
public void Show() {
System.out.println("生产出了产品B");
}
}
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
class FactoryA extends Factory{
//工厂A类 - 生产A类产品
@Override
public Product Manufacture() {
return new ProductA();
}
}
class FactoryB extends Factory{
//工厂B类 - 生产B类产品
@Override
public Product Manufacture() {
return new ProductB();
}
}
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
public class FactoryPattern {
//生产工作流程
public static void main(String[] args){
//客户要产品A
FactoryA mFactoryA = new FactoryA();
mFactoryA.Manufacture().Show();
//客户要产品B
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().Show();
}
}
4. 优点
-
更符合开-闭原则:新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
-
符合单一职责原则:每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
-
不使用静态工厂方法,可以形成基于继承的等级结构。
5. 缺点
-
添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类, 系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
-
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术 ,增加了系统的实现难度。
-
虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
-
一个具体工厂只能创建一种具体产品
6. 应用场景
-
当一个类不知道它所需要的对象的类时在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可;
-
当一个类希望通过其子类来指定创建对象时在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
-
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
设计模式之:抽象工厂模式。
1.1 定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。
抽象工厂模式与工厂方法模式最大的区别: 抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类
1.2 主要作用
2.1使用步骤
abstract class Factory{
public abstract Product ManufactureContainer();
public abstract Product ManufactureMould();
}
步骤2: 创建抽象产品族类 ,定义具体产品的公共接口;
abstract class AbstractProduct{
public abstract void Show();
}
步骤3: 创建抽象产品类 ,定义具体产品的公共接口
abstract class ContainerProduct extends AbstractProduct{
//容器产品抽象类
@Override
public abstract void Show();
}
abstract class MouldProduct extends AbstractProduct{
//模具产品抽象类
@Override
public abstract void Show();
}
步骤4: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
class ContainerProductA extends ContainerProduct{//容器产品A类
@Override
public void Show() {
System.out.println("生产出了容器产品A");
}
}
class ContainerProductB extends ContainerProduct{//容器产品B类
@Override
public void Show() {
System.out.println("生产出了容器产品B");
}
}
class MouldProductA extends MouldProduct{//模具产品A类
@Override
public void Show() {
System.out.println("生产出了模具产品A");
}
}
class MouldProductB extends MouldProduct{//模具产品B类
@Override
public void Show() {
System.out.println("生产出了模具产品B");
}
}
步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
class FactoryA extends Factory{//A厂 - 生产模具+容器产品
@Override
public Product ManufactureContainer() {
return new ContainerProductA();
}
@Override
public Product ManufactureMould() {
return new MouldProductA();
}
}
class FactoryB extends Factory{ //B厂 - 生产模具+容器产品
@Override
public Product ManufactureContainer() {
return new ContainerProductB();
}
@Override
public Product ManufactureMould() {
return new MouldProductB();
}
}
步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例
public class AbstractFactoryPattern {//生产工作流程
public static void main(String[] args){
FactoryA mFactoryA = new FactoryA();
FactoryB mFactoryB = new FactoryB();
//A厂当地客户需要容器产品A
mFactoryA.ManufactureContainer().Show();
//A厂当地客户需要模具产品A
mFactoryA.ManufactureMould().Show();
//B厂当地客户需要容器产品B
mFactoryB.ManufactureContainer().Show();
//B厂当地客户需要模具产品B
mFactoryB.ManufactureMould().Show();
}
}
4. 优点
-
降低耦合抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;
-
更符合开-闭原则新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
-
符合单一职责原则每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
-
不使用静态工厂方法,可以形成基于继承的等级结构。简单工厂模式的工厂类使用静态工厂方法
5. 缺点
抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。6. 应用场景
在了解了优缺点后,我总结了工厂方法模式的应用场景: -
一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
-
这个系统有多个系列产品,而系统中只消费其中某一系列产品
-
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。