java工厂模式


今天也是干的一天
在这里插入图片描述

工厂模式

工厂模式分为简单工厂、工厂方法与抽象工厂模式;

传统方式创建一类对象

在这里插入图片描述

Pizza.java

package com.yxj.factory.simplefactory.pizzastore.pizza;

//将Pizza 类做成抽象
public abstract class Pizza {
	protected String name; //名字

	//准备原材料, 不同的披萨不一样,因此,我们做成抽象方法
	public abstract void prepare();

	
	public void bake() {
		System.out.println(name + " baking;");
	}

	public void cut() {
		System.out.println(name + " cutting;");
	}

	//打包
	public void box() {
		System.out.println(name + " boxing;");
	}

	public void setName(String name) {
		this.name = name;
	}
}

CheesePizza.java

package com.yxj.factory.simplefactory.pizzastore.pizza;

public class CheesePizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		System.out.println(" 给制作奶酪披萨 准备原材料 ");
	}

}

GreekPizza.java


package com.yxj.factory.simplefactory.pizzastore.pizza;

public class GreekPizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		System.out.println(" 给希腊披萨 准备原材料 ");
	}

}

OrderPizza.java



public class OrderPizza {

	//构造器
	public OrderPizza() {
		Pizza pizza = null;
		String orderType; // 订购披萨的类型
		do {
			orderType = getType();
			if (orderType.equals("greek")) {
				pizza = new GreekPizza();
				pizza.setName(" 希腊披萨 ");
			} else if (orderType.equals("cheese")) {
				pizza = new CheesePizza();
				pizza.setName(" 奶酪披萨 ");
			} else if (orderType.equals("pepper")) {
				pizza = new PepperPizza();
				pizza.setName("胡椒披萨");
			} else {
				break;
			}
			//输出pizza 制作过程
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
			
		} while (true);
	}
	// 写一个方法,可以获取客户希望订购的披萨种类
	private String getType() {
		try {
			BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("input pizza 种类:");
			String str = strin.readLine();
			return str;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}

}

PepperPizza.java


package com.yxj.factory.simplefactory.pizzastore.pizza;

public class PepperPizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		System.out.println(" 给胡椒披萨准备原材料 ");
	}

}

PizzaStore.java

package com.yxj.factory.simplefactory.pizzastore.order;

//相当于一个客户端,发出订购
public class PizzaStore {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new OrderPizza();
		
	}

}

优缺点

  • 简单、容易理解
  • 违反了OCP原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改已经写好的代码,或者尽可能少修改代码。
  • 比如我们这时要新增加一个Pizza的种类(CheesePizza披萨),我们需要做如下修改.
//新增 写
public class CheesePizza extends Pizza {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("奶酪pizza");
System.out.println(name + " preparing;");
}}
//增加一段代码 OrderPizza.java //写
if (ordertype.equals("greek")) {
pizza = new GreekPizza();
} else if (ordertype.equals("pepper")) {
pizza = new PepperPizza();
} else if (ordertype.equals("cheese")) {
pizza = new CheesePizza();
} else {
break;
}}
  • 也许有人会说,不就一个地方修改了代码吗?但是在工作中,可能在其他的地方也有创建Pizza代码,意味着其他的地方也要修改,而创建Pizza代码的地方,有很多处的情况下,就麻烦了。
  • 思路:把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该
    类就可,其它有创建到Pizza对象的代码就不需要修改了.-> 简单工厂模式

简单工厂模式

简单工厂模式是属于创建型模式、是工厂模式的一种。简单工厂模式就是由一个对象(对应一个SimpleFactory类)决定创建出哪一产品类的实例。
在这里插入图片描述
核心类SimpleFactory

public class SimpleFactory {

	
	
	//简单工厂模式 也叫 静态工厂模式 
	
	public static Pizza createPizza2(String orderType) {

		Pizza pizza = null;

		System.out.println("使用简单工厂模式2");
		if (orderType.equals("greek")) {
			pizza = new GreekPizza();
			pizza.setName(" 希腊披萨 ");
		} else if (orderType.equals("cheese")) {
			pizza = new CheesePizza();
			pizza.setName(" 奶酪披萨 ");
		} else if (orderType.equals("pepper")) {
			pizza = new PepperPizza();
			pizza.setName("胡椒披萨");
		}
		
		return pizza;
	}

}

OrderPizza2.java

public class OrderPizza2 {

	Pizza pizza = null;
	String orderType = "";
	// 构造器
	public OrderPizza2() {
		
		do {
			orderType = getType();
			pizza = SimpleFactory.createPizza2(orderType);

			// 输出pizza
			if (pizza != null) { // 订购成功
				pizza.prepare();
				pizza.bake();
				pizza.cut();
				pizza.box();
			} else {
				System.out.println(" 订购披萨失败 ");
				break;
			}
		} while (true);
	}

	// 写一个方法,可以获取客户希望订购的披萨种类
	private String getType() {
		try {
			BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("input pizza 种类:");
			String str = strin.readLine();
			return str;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}
}

  • 核心就是SimpleFactory的实现,使用该类负责实例的创建,符合OCP开闭原则;

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类;

package com.tuling.designpattern.factorymethod;

/**
 * @author 玄霄
 * @Slogan 致敬大师,致敬未来的你
 */
public class FactoryMethodTest {
    public static void main(String[] args) {
        Application application= new ConcreteProductB();
        Product   product=application.getObject();
        product.method1();

    }
}

interface Product{
    void method1();
}

class ProductA implements Product{

    @Override
    public void method1() {
        System.out.println( "ProductA.method1 executed." );
    }
}

class ProductB implements Product{

    @Override
    public void method1() {
        System.out.println( "ProductB.method1 executed." );
    }
}


// 简单工厂
class SimpleFactory{
    public static Product createProduct(String type){
        if ("A".equals( type )){
            return new ProductA();
        }

        return null;
    }
}

//  变化 , 共同点
abstract class Application {

    // 工厂方法
    public abstract Product createProduct();

    public Product getObject() {

        Product  product=createProduct();
        // ......这是公共不变的部分代码
        return product;
    }
}

class ConcreteProductA extends Application{

    @Override
    public Product createProduct() {
        ProductA productA=new ProductA();
        return productA;
    }
}


class ConcreteProductB extends Application{

    @Override
    public Product createProduct() {
        ProductB productB=new ProductB();
        return productB;
    }
}

应用场景与优点

  • 当你不知道改使用对象的确切类型的时候
  • 当你希望为库或框架提供扩展其内部组件的方法时

优点:

  • 将具体产品和创建者解耦
  • 符合单一职责原则
  • 符合开闭原则

抽象方法模式

提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们的具体的类
在这里插入图片描述

  • AbstractProductA:创建A类产品所实现的接口,该接口包含了A类产品中共有的方法;
interface IConnection{

    void connection();
}
  • ProductA1,ProductA2:A类的具体产品;
class MyConnection implements IConnection{

    @Override
    public void connection() {
        System.out.println("mysql: connect.");
    }
}
class OracleConnection implements IConnection{


    @Override
    public void connection() {
        System.out.println("oracle:connect.");
    }
}

  • AbstractProductB:创建B类产品所实现的接口,该接口包含了B类产品中共有的方法;
interface ICommand{

    void command();
}

  • ProductB1,ProductB2:B类的具体产品
class MyCommand implements ICommand{

    @Override
    public void command() {
        System.out.println("mysql: command.");
    }
}

class OracleCommand implements ICommand{

    @Override
    public void command() {
        System.out.println("oracle:command.;");
    }
}
  • AbstracyFactory:包含了创建的A类、B类产品的接口方法;
interface IDBComponent{

    IConnection getConnection();

    ICommand getCommand();
}
  • ConcreteFactory1: 创建 “1”系列的产品,即ProductA1,ProductB1;
//“1”在这里值的是MySQL
class MysqlDbComponent implements IDBComponent{

    @Override
    public IConnection getConnection() {
        return new MyConnection();
    }

    @Override
    public ICommand getCommand() {
        return new MyCommand();
    }
}
  • ConcreteFactory2: 创建 “2”系列的产品,即ProductA2,ProductB2;
//“2”在这里值的是Oracle系列
class OralceDbComponent implements IDBComponent{

    @Override
    public IConnection getConnection() {
        return new OracleConnection();
    }

    @Override
    public ICommand getCommand() {
        return new OracleCommand();
    }
}


应用场景

  • 程序需要处理不同系列的相关产品,但是您不希望它依赖于这些产品的具体类时
  • 可以使用抽象工厂

优点

  1. 可以确信你从工厂得到的产品彼此是兼容的。
  2. 可以避免具体产品和客户端代码之间的紧密耦合。
  3. 符合单一职责原则
  4. 符合开闭原则

JDK源码中的应用:

 java.sql.Connection 
 java.sql.Driver

工厂方法与抽象工厂的区别

当抽象工厂接口方法只有一个时,就变成了工厂方法模式;

千军万马一将在,探囊取物有何难

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值