GOF23设计模式(创建型模式)~ 工厂模式(含面向对象的六大基本原则,详细分析三种工厂方式的优略,代码示例清晰~,分析详细)

目录:

一:工厂模式的核心本质

二:关于面向对象的六大基本原则

三:工厂模式的三大类详解(代码示例,详细分析)


首先,上咱本GOF23所有工厂模式的分类表格!!!

创建型模式

单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式

结构型横式

适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式

行为型模式

模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式

 其中我们讲的工厂模式为创建型模式!!!!


一:工厂模式的核心本质

  1. 实现了创建者和调用者的分离,实例化对象,用工厂方法代替new操作。
  2. 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

我们要明确的一点,我们设计模式的基础是面向对象编程(Object Oriented Programming,OOP),只要是提及设计模式,肯定都是基于面向对象编程的,所以我们的设计模式要以面向对象的基本原则为基础!!!接下来,我给大家列出关于面向对象的六大基本原则!


二:面向对象的六大基本原则(其中OCP为总原则)

总原则:OCP(开闭原则, Open-Closed Principle)

对扩展开放,对修改关闭。设计功能模块的时候,应当使这个模块在不被修改的前提下可以被扩展(功能)

DIP(依赖倒转原则, Dependence Inversion Principle)

依赖抽象不依赖具体,高层模块不应该依赖底层模块,两者应该依赖抽象,抽象不应该依赖细节(具体实现),细节依赖抽象(依赖接口)

提高可维护性

LOD(迪米特法则, Law of demeter)

对象之间联系越少越好,对于对象的使用,方法调用,具体内部细节知道的越少越好(高内聚,低耦合) 可维护性强。(尽量少与其他类有关系,利于解耦)

SRP(单一职责原则,Single responsibility principle)

一个类或模块应该只做一件事(一个类或者模块对应一个功能类),高内聚,低耦合,专注于单一功能(高内聚)

ISP(接口隔离原则,Interface Segregation Principle)

一个接口最好只有一个方法(功能),让实现一个接口的类重写一种方法(功能)。针对不同功能应该有不同接口,使接口的功能有选择性,不强迫必须实现不需要的功能。

CRP(组合/聚合原则,Composite Reuse Principle)

尽量使用对象组合,而不是继承对象达到功能复用的目的,一个新对象A能使用已有对象B达到功能复用(B对象的功能),就不要通过继承(B)对象来达到功能复用

LSP(里氏替换原则,Liskov Substitution Principle)

对于父类出现的地方,都可以用子类代替(多态,继承)


三: 三大工厂模式剖析

详细分类:

简单工厂模式

用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)

工厂方法模式

用来生产同一等级结构中的固定产品。(支持增加任意产品)

抽象工厂模式

用来生产不同产品族的全部产品。(对于增加新的产品,无能为力,支持增加产品族)

 让我们一起来看看简单工厂模式!!

 首先我,定义了一个Instrument 接口(乐器)

package 二_工厂模式;

public interface Instrument {
    void sing();
}

然后定义了两个类Guitar Piano 继承Instrument 接口

package 二_工厂模式;

public class Guitar implements Instrument {
    @Override
    public void sing() {
        System.out.println("吉他~");
    }
}
package 二_工厂模式;

public class Piano implements Instrument {
    @Override
    public void sing() {
        System.out.println("钢琴~");
    }
}

在没有工厂的情况下:

package 二_工厂模式;

public class noFactory {
    public static void main(String[] args) {
        Instrument i1 = new Guitar();
        Instrument i2 = new Piano();
        i1.sing();
        i2.sing();
    }
}

发现实例化出Guitar和Piano的两个对象要和Instrument接口以及这两个实现类都要打交道,有些臃肿,于是我们引入了工厂模式

1 . 简单工厂模式

在前面代码的基础上定义一个工厂类InstrumentFactory,其中的方法都定义为静态方法,直接通过类调用,其中创建对象有两种实现方式,在一下代码中给出!!

package 二_工厂模式;

public class InstrumentFactory {
    public static Guitar creatGuitar() {
        return new Guitar();
    }

    public static Piano creatPiano() {
        return new Piano();
    }

    //或者这样实现
    public static Instrument creatInstrument(String type) {
        Instrument i = null;
        if ("吉他".equals(type))
            i = new Guitar();
        else if ("钢琴".equals(type))
            i = new Piano();
        return i;
    }
}

然后我们进行实例化只用和工厂打交道

package 二_工厂模式;

public class simpleFactory {
    public static void main(String[] args) {
        InstrumentFactory.creatGuitar().sing();
        InstrumentFactory.creatPiano().sing();
        //或者这样实现
        InstrumentFactory.creatInstrument("吉他").sing();
        InstrumentFactory.creatInstrument("钢琴").sing();
    }
}

相比没有工厂的情况下,我们减少了在主函数里创建一个对象需要接触的类或者接口,实现了创建者和调用者的分离,实例化对象,用工厂方法代替new操作!!!

但是要增加新的类,比如"贝斯"类,必须修改工厂里已有的代码!!这是简单工厂模式的一个弊端!!

总结:

  • 简单工厂模式也叫静态工厂模式、就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例
  • 对于增加新产品必须修改已有的代码!违反了OCP原则!不修改代码的话,是无法扩展的。

2. 工厂方法模式

同样在最前面的代码基础上增加一个工厂接口creatFactory

package 二_工厂模式;

public interface creatFactory {
    Instrument creat();
}

然后再增加两个具体的工厂实现类GuitarCreatPianoCreat继承creatFactory接口

package 二_工厂模式;

public class GuitarCreat implements creatFactory {
    @Override
    public Instrument creat() {
        return new Guitar();
    }
}
package 二_工厂模式;

public class PianoCreat implements creatFactory {
    @Override
    public Instrument creat() {
        return new Piano();
    }
}

然后我们进行实例化只用分别和这两个工厂打交道

package 二_工厂模式;

public class FunctionFactory {
    public static void main(String[] args) {
        new GuitarCreat().creat().sing();
        new PianoCreat().creat().sing();
    }
}

相比简单工厂法,如果要增加新的类,比如"贝斯"类,不用修改工厂里已有的代码,直接多加一个新的贝斯工厂实现工厂接口即可!!这是工厂方法模式的一个好处!!! 

 总结:

  • 为了避免简单工厂模式的缺点,此方法满足了总原则:OCP原则
  • 工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。

3.抽象工厂模式

简介:

  • 用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
  • 抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业努分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式

首先我们明白什么是产品族,接下来我会以实现一个汽车工厂为例

GOF23设计模式(创建型模式)~ 工厂模式(含面向对象的六大基本原则,详细分析三种工厂方式的优略,代码示例清晰~,分析详细)_第1张图片

我们把汽车拆分为Engine(发动机)、Seat(座位)、Tyre(轮胎)三部分

分别创建这三个接口~~

汽车就是一种产品,我们将汽车这个产品分为两个产品族:

  1. 昂贵的汽车,包括LuxuryEngine、LuxurySeat、LuxuryTyre三个部分,分别实现了以上三个对应的接口
  2. 低端的汽车,包括LowEngine、LowSeat、LowTyre三个部分,分别实现了以上三个对应的接口

package 二_工厂模式_抽象工厂模式;

 

//发动机

public interface Engine {

    void noice();//噪音

    void price();//价格

}

 

class LowEngine implements Engine {

    @Override

    public void noice() {

        System.out.println("噪音很大");

    }

 

    @Override

    public void price() {

        System.out.println("价格便宜");

    }

}

 

class LuxuryEngine implements Engine {

    @Override

    public void noice() {

        System.out.println("噪音很小");

    }

 

    @Override

    public void price() {

        System.out.println("价格昂贵");

    }

}

 

package 二_工厂模式_抽象工厂模式;

 

//座位

public interface Seat {

    void comfortable();//舒适程度

    void functionality();//功能性

}

 

class LowSeat implements Seat {

    @Override

    public void comfortable() {

        System.out.println("不舒服");

    }

 

    @Override

    public void functionality() {

        System.out.println("功能性很差");

    }

}

 

class LuxurySeat implements Seat {

    @Override

    public void comfortable() {

        System.out.println("很舒适");

    }

 

    @Override

    public void functionality() {

        System.out.println("功能性很强大");

    }

}

 

package 二_工厂模式_抽象工厂模式;

 

//轮胎

public interface Tyre {

    void durability();//耐用性

    void security();//安全性

}

 

class LowTyre implements Tyre {

    @Override

    public void durability() {

        System.out.println("耐用性很差");

    }

 

    @Override

    public void security() {

        System.out.println("安全性很差");

    }

}

 

class LuxuryTyre implements Tyre {

    public void durability() {

        System.out.println("耐用性很好");

    }

 

    @Override

    public void security() {

        System.out.println("安全性很好");

    }

}

 接下来,我们创建一个汽车工厂的接口CarFactory,并且为旗下的两个产品族分别创建工厂LowFactoryLuxuryFactory实现以上接口,用来创建Engine(发动机)、Seat(座位)、Tyre(轮胎)

package 二_工厂模式_抽象工厂模式;

public interface CarFactory {
    Engine createEngine();
    Seat createSeat();
    Tyre createTyre();
}

class LowFactory implements CarFactory {

    @Override
    public Engine createEngine() {
        return new LowEngine();
    }

    @Override
    public Seat createSeat() {
        return new LowSeat();
    }

    @Override
    public Tyre createTyre() {
        return new LowTyre();
    }
}

class LuxuryFactory implements CarFactory {

    @Override
    public Engine createEngine() {
        return new LuxuryEngine();
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat();
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();
    }
}

 最后,我们在一个主方法里测试,通过两个产品族的工厂直接分别创建两个产品族汽车的轮子,座椅和发动机

package 二_工厂模式_抽象工厂模式;

public class client {
    public static void main(String[] args) {
        //高端汽车产品族
        CarFactory factory1 = new LuxuryFactory();
        factory1.createEngine().noice();
        factory1.createEngine().price();
        factory1.createSeat().comfortable();
        factory1.createSeat().functionality();
        factory1.createTyre().durability();
        factory1.createTyre().security();
        //低端汽车产品族
        CarFactory factory2 = new LowFactory();
        factory2.createEngine().noice();
        factory2.createEngine().price();
        factory2.createSeat().comfortable();
        factory2.createSeat().functionality();
        factory2.createTyre().durability();
        factory2.createTyre().security();
    }
}

根据结果,我们已经创建成功,这就是关于抽象工厂模式的一个实例!!!


THE END-------------------------------------------------------------------------------------------------------

你可能感兴趣的:(java)