设计模式第五次作业---简单工厂模式、工厂方法模式、抽象工厂模式

简单工厂模式

工厂类角色Creator:工厂类在客户端的直接控制下( Create方法)创建产品对象。
抽象产品角色Product:定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。
具体产品角色ConcreteProduct:定义工厂具体加工出的对象。

简单工厂模式——实现简单运算

代码一

import java.util.Scanner;

public class main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入数字A:");
		String strA = sc.nextLine();
		System.out.println("请输入运算符号(+、—、*、/):");
		String stroper = sc.nextLine();
		System.out.println("请输入数字B:");
		String strB = sc.nextLine();
		Operation oper = OperationFactory.createOperation(stroper.charAt(0));
		oper.setNumberA(Double.parseDouble(strA));
		oper.setNumberB(Double.parseDouble(strB));
		System.out.println("结果是:" + oper.getResult());

	}
}

abstract class Operation {
	private double numberA = 0;
	private double numberB = 0;
	boolean flag = true;

	public double getNumberA() {
		return numberA;
	}

	public void setNumberA(double numberA) {
		this.numberA = numberA;
	}

	public double getNumberB() {
		return numberB;
	}

	public void setNumberB(double numberB) {
		this.numberB = numberB;
	}

	public abstract double getResult();
}

//加法类
class OperationAdd extends Operation {

	public double getResult() {
		return getNumberA() + getNumberB();
	}
}

//减法类
class OperationSub extends Operation {

	public double getResult() {
		return getNumberA() - getNumberB();
	}
}

//乘法类
class OperationMul extends Operation {

	public double getResult() {
		return getNumberA() * getNumberB();
	}
}

//除法类
class OperationDiv extends Operation {

	public double getResult() {
		return getNumberA() / getNumberB();
	}
}

//简单运算工厂类
class OperationFactory {
	public static Operation createOperation(char operate) {
		Operation oper = null;
		switch (operate) {
		case '+':
			oper = new OperationAdd();
			break;
		case '-':
			oper = new OperationSub();
			break;
		case '*':
			oper = new OperationMul();
			break;
		case '/':
			oper = new OperationDiv();
			break;
		}
		return oper;
	}
}

实现二

import java.util.Scanner;

public class main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入数字A:");
		String strA = sc.nextLine();
		System.out.println("请输入运算符号(+、—、*、/):");
		String stroper = sc.nextLine();
		System.out.println("请输入数字B:");
		String strB = sc.nextLine();
		Operation oper = OperationFactory.createOperation(stroper.charAt(0));
		oper.setNumberA(Double.parseDouble(strA));
		oper.setNumberB(Double.parseDouble(strB));
		System.out.println("结果是:" + oper.getResult());

	}
}

abstract class Operation {
	private double numberA = 0;
	private double numberB = 0;
	boolean flag = true;

	public double getNumberA() {
		return numberA;
	}

	public void setNumberA(double numberA) {
		this.numberA = numberA;
	}

	public double getNumberB() {
		return numberB;
	}

	public void setNumberB(double numberB) {
		this.numberB = numberB;
	}

	public abstract double getResult();
}

//加法类
class OperationAdd extends Operation {

	public double getResult() {
		return getNumberA() + getNumberB();
	}
}

//减法类
class OperationSub extends Operation {

	public double getResult() {
		return getNumberA() - getNumberB();
	}
}

//乘法类
class OperationMul extends Operation {

	public double getResult() {
		return getNumberA() * getNumberB();
	}
}

//除法类
class OperationDiv extends Operation {

	public double getResult() {
		return getNumberA() / getNumberB();
	}
}

//简单运算工厂类——增加求m的n次方运算
class OperationFactory {
	public static Operation createOperation(char operate) {
		Operation oper = null;
		switch (operate) {
		case '+':
			oper = new OperationAdd();
			break;
		case '-':
			oper = new OperationSub();
			break;
		case '*':
			oper = new OperationMul();
			break;
		case '/':
			oper = new OperationDiv();
			break;
		case '^':
			oper = new OperationMN();
		}
		return oper;
	}
}

//增加求m的n次方类
class OperationMN extends Operation {

	public double getResult() {
		double r = 0;
		double m = getNumberA();
		int n = (int) getNumberB();
		for (int i = 0; i <= n; i++) {
			r = r * m;
		}
		return r;
	}

}

优点:

二厂类中包含了必妥的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖

缺点:

在某种和度上违背了开放-封闭原则: 系统扩展困难,一旦添加新产品就得修改二厂类。
对工厂类过于依赖: 厂 类集中了所有产品创建逻辑,一旦不能正常二作, 整个系统都要受到影响。

工厂方法模式—简单计算器


public class main1 {

	public static void main(String[] args) {
		IFactory iFactory = new AddFactory();
		Operation operation = iFactory.CreateOperation();
		operation.setNumberA(1);
		operation.setNumberB(2);
		double result = operation.GetResult();
		System.out.println("结果: " + result);
	}

}

interface IFactory {
	Operation CreateOperation();
}

//加法类工厂
class AddFactory implements IFactory {

	public Operation CreateOperation() {
		return new OperationAdd();
	}
}

// 减法类工厂
class SubFactory implements IFactory {

	public Operation CreateOperation() {
		return new OperationSub();
	}
}

// 乘法类工厂
class MulFactory implements IFactory {

	public Operation CreateOperation() {
		return new OperationMul();
	}
}

// 除法类工厂
class DivFactory implements IFactory {

	public Operation CreateOperation() {
		return new OperationDiv();
	}
}

//运算类
abstract class Operation {
	private double numberA = 0;
	private double numberB = 0;

	public double getNumberA() {
		return numberA;
	}

	public void setNumberA(double numberA) {
		this.numberA = numberA;
	}

	public double getNumberB() {
		return numberB;
	}

	public void setNumberB(double numberB) {
		this.numberB = numberB;
	}

	public abstract double GetResult();

}

//加法类
class OperationAdd extends Operation {

	public double GetResult() {
		// TODO Auto-generated method stub
		double result = 0;
		result = getNumberA() + getNumberB();
		return result;
	}
}

//除法类
class OperationDiv extends Operation {

	@Override
	public double GetResult() {
		double result = 0;
		result = getNumberA() / getNumberB();
		return result;
	}
}

//乘法类
class OperationMul extends Operation {

	@Override
	public double GetResult() {
		double result = 0;
		result = getNumberA() * getNumberB();
		return result;
	}

}

//减法类
class OperationSub extends Operation {

	@Override
	public double GetResult() {
		// TODO Auto-generated method stub
		double result = 0;
		result = getNumberA() - getNumberB();
		return result;
	}

}

抽象工厂模式—数据库访问程序
版本1:

public class main2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		User user = new User();
		SqlserverUser sqlserverUser = new SqlserverUser();
		sqlserverUser.Insert(user);
		sqlserverUser.GetUser(1);

	}

}

//用户对象
class User {
	private int _id;
	private String _name;

	public int get_id() {
		return _id;
	}

	public void set_id(int _id) {
		this._id = _id;
	}

	public String get_name() {
		return _name;
	}

	public void set_name(String _name) {
		this._name = _name;
	}
}

//sql Server数据库操作user
class SqlserverUser {
	public void Insert(User user) {
		System.out.println("SQL Server中给User表添加一条记录");
	}

	public User GetUser(int id) {
		System.out.println("SQL Server中根据id得到User表中的一条纪录");
		return null;
	}
}
  • 分析:这里因为SqlserverUser sqlserverUser=new SqlserverUser();
  • 这行代码写死在SqlServer了,即没有灵活性。 如果这里具有灵活性(多态),那么在执行 sqlserverUser.Insert(user);
  • sqlserverUser.GetUser(1); 这两句代码时就不用考虑是哪个数据库了。

版本二:使用抽象工厂模式。

public class main2 {

	public static void main(String[] args) {
		User user = new User();
		IFactory factory = new SqlServerFactory();
		IUser iUser = factory.CreateUser();
		iUser.InsertUser(user);
		iUser.GetUser(1);
		Department department = new Department();
		IDepartment iDepartment = factory.createDepartment();
		iDepartment.Insert(department);
		iDepartment.GetDeparment(1);

	}
}

//用户接口--->抽象产品A
interface IUser {
	void InsertUser(User user);

	User GetUser(int id);

}

//部门接口--->抽象产品B
interface IDepartment {
	void Insert(Department department);

	Department GetDeparment(int id);

}

//抽象工厂
interface IFactory {
	IUser CreateUser();

	IDepartment createDepartment();

}

//Access数据库访问--->具体工厂1
class AccessFactory implements IFactory {

	@Override
	public IUser CreateUser() {
		return new AccessUser();// 类的实例化放在子类中,封装new AccessUser()所造成的变化
	}

	@Override
	public IDepartment createDepartment() {
		return new AccessDepartment();
	}

}

//SqlServer数据库--->具体工厂2
class SqlServerFactory implements IFactory {

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

	@Override
	public IDepartment createDepartment() {
		return new SqlserverDepartment();
	}

}

//具体产品类A
class SqlserverUser implements IUser {

	@Override
	public void InsertUser(User user) {
		System.out.println("SQL Server中給User表添加一条记录");

	}

	@Override
	public User GetUser(int id) {
		System.out.println("SQL Server中根據id得到User表中的一条记录");
		return null;
	}

}

//具体产品类A
class AccessUser implements IUser {

	@Override
	public void InsertUser(User user) {
		System.out.println("在Access中給User表添加一条记录");
	}

	@Override
	public User GetUser(int id) {
		System.out.println("在Access中根據id查找User表的一条记录");
		return null;
	}

}

//具体产品类B
class SqlserverDepartment implements IDepartment {

	@Override
	public void Insert(Department department) {
		System.out.println("在SQL Server中給department表新增一条记录");
	}

	@Override
	public Department GetDeparment(int id) {
		System.out.println("在SQL Server中根據id從department表中取出一条记录");
		return null;
	}

}

//具体产品类B
class AccessDepartment implements IDepartment {

	@Override
	public void Insert(Department department) {
		System.out.println("在Access中給Department表新增一条记录");

	}

	@Override
	public Department GetDeparment(int id) {
		System.out.println("在Access中根據id得到department表中的一条记录");
		return null;
	}

}

//用户类
class User {
	private int _id;
	private String _name;

	public int get_id() {
		return _id;
	}

	public void set_id(int _id) {
		this._id = _id;
	}

	public String get_name() {
		return _name;
	}

	public void set_name(String _name) {
		this._name = _name;
	}

}

分析:
1、在使用了抽象工厂模式后,通过IFactory factory=new SqlServerFactory();这行代码来实现数据库的切换。
2、如果要新增一个表对象(抽象产品),则需要大量的改动。

版本三:借助简单工厂改进抽象工厂
去掉原有的IFactory抽象工厂即两个具体工厂,用下面的DataAccess类来代替。

public class main2 {
    public static void main(String[] args) {
        User user=new User();
        Department department=new Department();
        IUser iUser=DataAccess.CreateUser();//直接通过DataAccess获得想要的表对象
        iUser.InsertUser(user);
        iUser.GetUser(1);

        IDepartment iDepartment=DataAccess.CreateDepartment();
        iDepartment.Insert(department);
        iDepartment.GetDeparment(1);
    }

}
public class DataAccess {
    private static String db="Sqlserver";

  // 根据db来决定实例化不同的类
    public static IUser CreateUser(){
        IUser result=null;
        switch (db) {
        case "Sqlserver":
            result=new SqlserverUser();
            break;
        case "Access":
            result=new AccessUser();
            break;
        }
        return result;
    }

    public static IDepartment CreateDepartment(){
        IDepartment result=null;
        switch (db) {
        case "Sqlserver":
            result=new SqlserverDepartment();
            break;
        case "Access":
            result=new AccessDepartment();
            break;
        }
        return result;
    }

}

分析:
这样把表对象的创建放入DataAccess中,在DataAccess中通过db来判断此时是哪一个数据库,从而实例化相应的表对象,当需要修改数据库时,只需要改动db即可。
另外,在DataAccess中有大量的分支判断,代码可以通过反射进一步优化,让db变量的值在客户端被指定,而不是事前就在DataAccess中写出。

// 数据库名称
    private static String db = "Sqlserver";
    // 包名----》改成SqlserverDepartment等类所在的包名
    private static String AssemblyName = "com.hwj.www.model15.version4.";

    /*
     * 根据db来决定实例化不同的类
     */
    public static IUser CreateUser() throws Exception {
        IUser result = null;
        //通过反射来实例化相应
        result = (IUser) Class.forName(AssemblyName + db + "User").newInstance();//SqlserverUser AccessUser
        return result;
    }

    public static IDepartment CreateDepartment() throws Exception {
        IDepartment result = null;
        result = (IDepartment) Class.forName(AssemblyName + db + "Department").newInstance();//SqlserverDepartment AccessDepartment
        return result;
    }

}

工厂方法模式:
在新增一个新产品时,就要新增一个具体工厂和一个具体产品类,这样程序的拓展性就有了提高,符合了开闭原则,避免了简单工厂模式的缺点.
但是,新增产品时需要新增两个类,会增加代码量,可谓是有舍有得,具体如何要结合具体情况来使用。
抽象工厂模式:
所有工厂模式的一般形式,当抽象工厂模式退化到只有一个产品登级结构时,就变成了工厂方法模式。当工厂方法模式的工厂类只有一个时,且工厂方法为静态方法时,则又变成了简单工厂模式。
与工厂方法模式相似,抽象工厂模式隔离了具体类的生成,让客户端不清楚具体什么样的对象被创建。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sweet y y y y u

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值