Go和Java实现抽象工厂模式

2023-12-15 23:39:44

Go和Java实现抽象工厂模式

本文通过简单数据库操作案例来说明抽象工厂模式的使用,使用Go语言和Java语言实现。

1、抽象工厂模式

抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创

建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工

厂模式提供对象。

  • 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

  • 主要解决:主要解决接口选择的问题。

  • 何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

  • 如何解决:在一个产品族里面,定义多个产品。

  • 关键代码:在一个工厂里聚合多个同类产品。

  • 应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产

    品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、

    时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,但有利于说明抽象工

    厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每

    次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是

    衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产

    品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

  • 优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

  • 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里

    面加代码。

  • 使用场景:1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

  • 注意事项:产品族难扩展,产品等级易扩展。

  • 适用性:

    一个系统要独立于它的产品的创建、组合和表示时。

    一个系统要由多个产品系列中的一个来配置时。

    当你要强调一系列相关的产品对象的设计以便进行联合使用时。

    当你提供一个产品类库,而只想显示它们是接口而不是实现时。

2、Go实现简单数据库操作

我们通过 sqlserver 和 access 两种数据库对用户表和部门表进行操作。

package factory

// 操作的用户表
type User struct {
	Id   int
	Name string
}
package factory

// 用户表的操作
type IUser interface {
	InsertUser(User) bool
	GetUser(int)
}
package factory

import "fmt"

// SqlServer数据库操作用户表
type SqlServerUser struct {
}

func (sqlServerUser *SqlServerUser) InsertUser(user User) bool {
	fmt.Println("SqlServer数据库插入用户!")
	return true
}

func (sqlServerUser *SqlServerUser) GetUser(int) {
	fmt.Println("SqlServer数据库查询用户!")
}
package factory

import "fmt"

// Access数据库操作用户表
type AccessUser struct {
}

func (accessUser *AccessUser) InsertUser(user User) bool {
	fmt.Println("Access数据库插入用户!")
	return true
}

func (accessUser *AccessUser) GetUser(int) {
	fmt.Println("Access数据库查询用户!")
}
package factory

// 操作的部门表
type Deployment struct {
	Id   int
	Name string
}
package factory

// 部门表的操作
type IDeployment interface {
	InsertDeployment(Deployment) bool
	GetDeployment(int)
}
package factory

import "fmt"

// SqlServer数据库操作部门表
type SqlServerDeployment struct {
}

func (sqlServerDeployment *SqlServerDeployment) InsertDeployment(deployment Deployment) bool {
	fmt.Println("SqlServer数据库插入部门!")
	return true
}

func (sqlServerDeployment *SqlServerDeployment) GetDeployment(int) {
	fmt.Println("SqlServer数据库查询部门!")
}
package factory

import "fmt"

// Access数据库操作部门表
type AccessDeployment struct {
}

func (accessDeployment *AccessDeployment) InsertDeployment(deployment Deployment) bool {
	fmt.Println("Access数据库插入部门!")
	return true
}

func (accessDeployment *AccessDeployment) GetDeployment(int) {
	fmt.Println("Access数据库查询部门!")
}
package factory

// 创建用户和部门操作的接口
type IFactory interface {
	CreateUser() IUser
	CreateDeployment() IDeployment
}
package factory

// Access数据库工厂
type AccessFactory struct {
}

func (accessFactory *AccessFactory) CreateUser() IUser {
	return &AccessUser{}
}

func (accessFactory *AccessFactory) CreateDeployment() IDeployment {
	return &AccessDeployment{}
}
package factory

// SqlServer数据库工厂
type SqlServerFactory struct {
}

func (sqlServerFactory *SqlServerFactory) CreateUser() IUser {
	return &SqlServerUser{}
}

func (sqlServerFactory *SqlServerFactory) CreateDeployment() IDeployment {
	return &SqlServerDeployment{}
}
package constant

const (
	SqlServer = "sqlserver"
	Access    = "access"
)
package factory

import "proj/constant"

// 用一个简单工厂封装抽象工厂
type FactoryCreate struct {
}

func (factoryCreate *FactoryCreate) NewFactory(dbType string) IFactory {
	switch dbType {
	case constant.SqlServer:
		return &SqlServerFactory{}
	case constant.Access:
		return &AccessFactory{}
	}
	return nil
}
package main

import (
	"fmt"
	"proj/constant"
	. "proj/factory"
)

// 测试
func main() {

	// 全局变量
	var factory IFactory
	var iUser IUser
	var iDeployment IDeployment
	// 操作用户
	user := User{}
	deployment := Deployment{}

	// SqlServer操作
	factory = &SqlServerFactory{}
	iUser = factory.CreateUser()
	iUser.InsertUser(user)
	iUser.GetUser(1)
	iDeployment = factory.CreateDeployment()
	iDeployment.InsertDeployment(deployment)
	iDeployment.GetDeployment(1)

	// Access操作
	factory = &AccessFactory{}
	iUser = factory.CreateUser()
	iUser.InsertUser(user)
	iUser.GetUser(1)
	iDeployment = factory.CreateDeployment()
	iDeployment.InsertDeployment(deployment)
	iDeployment.GetDeployment(1)

	fmt.Println("========================")

	// 简单工厂封装工厂方法
	factoryCreate := FactoryCreate{}

	// ==========SqlServer的工厂==========
	factory = factoryCreate.NewFactory(constant.SqlServer)
	iUser = factory.CreateUser()
	iUser.InsertUser(user)
	iUser.GetUser(1)
	iDeployment = factory.CreateDeployment()
	iDeployment.InsertDeployment(deployment)
	iDeployment.GetDeployment(1)

	// ==========Access的工厂==========
	factory = factoryCreate.NewFactory(constant.Access)
	iUser = factory.CreateUser()
	iUser.InsertUser(user)
	iUser.GetUser(1)
	iDeployment = factory.CreateDeployment()
	iDeployment.InsertDeployment(deployment)
	iDeployment.GetDeployment(1)
}
# 程序输出
SqlServer数据库插入用户!
SqlServer数据库查询用户!
SqlServer数据库插入部门!
SqlServer数据库查询部门!
Access数据库插入用户!
Access数据库查询用户!
Access数据库插入部门!
Access数据库查询部门!
========================
SqlServer数据库插入用户!
SqlServer数据库查询用户!
SqlServer数据库插入部门!
SqlServer数据库查询部门!
Access数据库插入用户!
Access数据库查询用户!
Access数据库插入部门!
Access数据库查询部门!

3、Java实现简单数据库操作

package com.factory;

// 操作的用户表
public class User {

    private int Id;
    private String Name;

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
}
package com.factory;

// 用户表的操作
public interface IUser {

    boolean InsertUser(User user);

    void GetUser(int id);
}
package com.factory;

// SqlServer数据库操作用户表
public class SqlServerUser implements IUser {

    @Override
    public boolean InsertUser(User user) {
        System.out.println("SqlServer数据库插入用户!");
        return true;
    }

    @Override
    public void GetUser(int id) {
        System.out.println("SqlServer数据库查询用户!");
    }
}
package com.factory;

// Access数据库操作用户表
public class AccessUser implements IUser {

    @Override
    public boolean InsertUser(User user) {
        System.out.println("Access数据库插入用户!");
        return true;
    }

    @Override
    public void GetUser(int id) {
        System.out.println("Access数据库查询用户!");
    }
}
package com.factory;

// 操作的部门表
public class Deployment {

    private int Id;
    private String Name;

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
}
package com.factory;

// 部门表的操作
public interface IDeployment {

    boolean InsertDeployment(Deployment deployment);

    void GetDeployment(int id);
}
package com.factory;

// Access数据库操作部门表
public class AccessDeployment implements IDeployment {

    @Override
    public boolean InsertDeployment(Deployment deployment) {
        System.out.println("Access数据库插入部门!");
        return true;
    }

    @Override
    public void GetDeployment(int id) {
        System.out.println("Access数据库查询部门!");
    }
}
package com.factory;

// SqlServer数据库操作部门表
public class SqlServerDeployment implements IDeployment {

    @Override
    public boolean InsertDeployment(Deployment deployment) {
        System.out.println("SqlServer数据库插入部门!");
        return true;
    }

    @Override
    public void GetDeployment(int id) {
        System.out.println("SqlServer数据库查询部门!");
    }
}
package com.factory;

// 创建用户和部门操作的接口
public interface IFactory {
    IUser CreateUser();

    IDeployment CreateDeployment();
}
package com.factory;

// Access数据库工厂
public class AccessFactory implements IFactory {

    @Override
    public IUser CreateUser() {
        return new AccessUser();
    }

    @Override
    public IDeployment CreateDeployment() {
        return new AccessDeployment();
    }
}
package com.factory;

// SqlServer数据库工厂
public class SqlServerFactory implements IFactory {

    @Override
    public IUser CreateUser() {
        return new SqlServerUser();
    }

    @Override
    public IDeployment CreateDeployment() {
        return new SqlServerDeployment();
    }
}
package com.factory;

// 用一个简单工厂封装抽象工厂
public class FactoryCreate {

    public IFactory NewFactory(DbType dbType) {
        switch (dbType) {
            case SQLSERVER:
                return new SqlServerFactory();
            case ACCESS:
                return new AccessFactory();
        }
        return null;
    }
}
package com.factory;

public class Test {

    public static void main(String[] args) {

        // 全局变量
        IFactory factory = null;
        IUser iUser = null;
        IDeployment iDeployment = null;

        // 操作用户
        User user = new User();
        Deployment deployment = new Deployment();

        // SqlServer操作
        factory = new SqlServerFactory();
        iUser = factory.CreateUser();
        iUser.InsertUser(user);
        iUser.GetUser(1);
        iDeployment = factory.CreateDeployment();
        iDeployment.InsertDeployment(deployment);
        iDeployment.GetDeployment(1);

        // Access操作
        factory = new AccessFactory();
        iUser = factory.CreateUser();
        iUser.InsertUser(user);
        iUser.GetUser(1);
        iDeployment = factory.CreateDeployment();
        iDeployment.InsertDeployment(deployment);
        iDeployment.GetDeployment(1);

        System.out.println("========================");

        // 简单工厂封装工厂方法
        FactoryCreate factoryCreate = new FactoryCreate();

        // ==========SqlServer的工厂==========
        factory = factoryCreate.NewFactory(DbType.SQLSERVER);
        iUser = factory.CreateUser();
        iUser.InsertUser(user);
        iUser.GetUser(1);
        iDeployment = factory.CreateDeployment();
        iDeployment.InsertDeployment(deployment);
        iDeployment.GetDeployment(1);

        // ==========Access的工厂==========
        factory = factoryCreate.NewFactory(DbType.ACCESS);
        iUser = factory.CreateUser();
        iUser.InsertUser(user);
        iUser.GetUser(1);
        iDeployment = factory.CreateDeployment();
        iDeployment.InsertDeployment(deployment);
        iDeployment.GetDeployment(1);
    }

}
# 程序输出
SqlServer数据库插入用户!
SqlServer数据库查询用户!
SqlServer数据库插入部门!
SqlServer数据库查询部门!
Access数据库插入用户!
Access数据库查询用户!
Access数据库插入部门!
Access数据库查询部门!
========================
SqlServer数据库插入用户!
SqlServer数据库查询用户!
SqlServer数据库插入部门!
SqlServer数据库查询部门!
Access数据库插入用户!
Access数据库查询用户!
Access数据库插入部门!
Access数据库查询部门!

4、简单工厂和工厂方法和抽象工厂类的区别

一句话概括工厂模式:

  • 简单工厂:一个工厂类,一个产品抽象类。

  • 工厂方法:多个工厂类,一个产品抽象类。

  • 抽象工厂:多个工厂类,多个产品抽象类。

生活中的工厂模式:

  • 简单工厂类:一个麦当劳店,可以生产多种汉堡。

  • 工厂方法类:一个麦当劳店,可以生产多种汉堡。一个肯德基店,也可以生产多种汉堡。

  • 抽象工厂类:百胜餐饮集团下有肯德基和百事公司,肯德基生产汉堡,百事公司生成百事可乐。

区别:

  • 简单工厂:只有唯一工厂(简单工厂),一个产品接口/抽象类,根据简单工厂中的静态方法来创建具体产品对

    象,适用于产品较少,几乎不扩展的情景。简单工厂中的方法集中了所有产品创建的逻辑,一旦要拓展新产品

    时,就不得不修改工厂类,并且会造成工厂的逻辑过于复杂,开发中很少使用。

  • 工厂方法:有多个工厂(抽象工厂+多个具体工厂),一个产品接口/抽象类,根据继承抽象工厂中的方法来多态

    创建具体产品对象,适用于一个类型的多个产品。工厂方法模式中,在新增一个新产品时,就要新增一个具体

    工厂和一个具体产品类,这样程序的拓展性就有了提高,符合了开闭原则,避免了简单工厂模式的缺点,但是

    新增产品时需要新增两个类,会增加代码量,可谓是有舍有得,具体如何要结合具体情况来使用,开发中经常

    使用。

  • 抽象方法:有多个工厂(抽象工厂+多个具体工厂),多个产品接口/抽象类,对产品子类进行分组,根据继承

    抽象工厂中的方法多态创建同组的不同具体产品对象,适用于多个类型的多个产品。抽象工厂模式是所有工厂

    模式的一般形式,当抽象工厂模式退化到只有一个产品等级结构时,就变成了工厂方法模式。当工厂方法模式

    的工厂类只有一个时,且工厂方法为静态方法时,则又变成了简单工厂模式。与工厂方法模式相似,抽象工厂

    模式隔离了具体类的生成,让客户端不清楚具体什么样的对象被创建。

抽象??模式与???法模式虽然主要意图都是为了解决接?选择问题,但在实现上抽象??是一个中???,创

建其他??的模式。

文章来源:https://blog.csdn.net/qq_30614345/article/details/130357957
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。