简单的工厂模式和工厂方法模式

1,简单的工厂模式

简单的说就是通过一个工厂类,对接口和类进行统一的管理。
我们先通过一个例题来说明一问题。

例子:我要买手机。

1,定义接口,用来买手机。

public interface OnPhone {
	/**
	 * 要购买的手机.
	 */
 void payPhone();
 
}

2,创建各种品牌的手机,实现上面的接口。

//小米
public class Mi implements OnPhone {
	@Override
	public void payPhone() {
		System.out.println("我是小米,万物基于MIUI,便宜又实惠,买了");
	}
}

//华为
public class Huawei implements OnPhone {

	@Override
	public void payPhone() {
		System.out.println("有点贵哈,但是没有啥大问题,买了");
	}
}

//苹果
public class Pingguo implements OnPhone {

	@Override
	public void payPhone() {
		System.out.println("这个更贵,不过有钱,任性,买了");
	}
}

接着就是我们的测试类

//买了两部手机
public class Text {
	
	public static void main(String[] args) {
		OnPhone mi = new Mi();
		mi.payPhone();
		
		OnPhone pingguo = new Pingguo();
		pingguo.payPhone();
	}
}

结果如下,

我是小米,万物基于MIUI,便宜又实惠,买了
这个更贵,不过有钱,任性,买了

我们观察上面的代码,其实是很好的完成了任务,但是我们的实现类和接口紧密的连接在了一起,耦合很高,在想一下,你要买手机,直接去找厂家买吗?,肯定是找一个代理人,或者是一个官方的软件呀,所以就引出了工厂模式。

我门在添加一个类Fragory,用它来管理手机,你要买什么只要找它就行。

public class Fragory {
	
	public static final int TYPE_MI = 1;//小米
	public static final int TYPE_HUA= 2;//华为
	public static final int TYPE_pingguo = 3;//苹果
	
	public static OnPhone createPhone(int type){
		switch(type){
		case TYPE_MI:
			return new Mi();
		case TYPE_HUA:
			return new Huawei();
		case TYPE_pingguo:
			return new Pingguo();
		default:
			System.out.println("没有这种手机");
			return null; 
		}
	}
	
}

只要调用这个类的静态工厂的方法里传入你需要购买的手机,然后就好了。如下所示:

public class Text {
	
	public static void main(String[] args) {
		OnPhone phone = Fragory.createPhone(Fragory.TYPE_MI);
		phone.payPhone();
	}
}

下面我们看一下这个模式的优点和缺点:

优点:

  • 通过一个静态的方法。就可以拿到所需要的东西,降低了耦合度。
  • 简单的工厂模式包含必要的判断逻辑,简单工厂实现了对象的创建和使用的分离。
  • 在不修改任何客户端代码的情况下更换和怎家新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  • 扩展性很差,如果有很多部手机的话,就好定义很多的类,每一个类对应着一部手机。而且还要修改静态工厂,这样就违反了封闭原则,而且会变得非常麻烦。
  • 工厂类的职责过重,如果静态工厂出现了问题,则整个系统都会出现问题。
  • 简单工厂的静态方法,使得工厂角色无法形成基于继承的等级结构。

工厂方法:

工厂方法则避免了 违反开放封闭原则,其实他的实现方法也非常简单,就是每个产品都对应着一个工厂。

如上面简单工厂,简单的说就是多个产品对应着一个静态的工厂方法。而工厂方法则是多个产品对应着多个工厂。下面我们看一下实现;

1,定义产品抽象类:

//产品抽象类
public abstract class Product {
	//显示产品
	public abstract void show();
	
}

2,定义产品实现类:

public class ProductMi extends Product{
	public void show() {
		System.out.println("生产小米手机");
	}
}


public class ProdcutHuaWei extends Product{
	public void show() {
		System.out.println("生产华为手机");
	}
}

public class ProductPingGuo extends Product{
	public void show() {
		System.out.println("生产苹果手机");
	}
}

3,定义工厂抽象类。

public abstract class Fractory {

	String name;
	
	//工厂名字
	public Fractory(String name){
		this.name = name;
		print();
	}
	public void print(){
		System.out.println(name);
	}
	//生产东西
	public abstract Product setProduct();
	
}

4,定义工厂的实现类,每个产品对应一个工厂实现类。

public class FractoryMi extends Fractory {

	public FractoryMi() {
		super("我是小米工厂");
	}
	@Override
	public Product setProduct() {
		// TODO Auto-generated method stub
		return new ProductMi();
	}
}

public class FractoryHuaWei extends Fractory{

	public FractoryHuaWei() {
		super("我是华为工厂");
	}

	@Override
	public Product setProduct() {
		return new ProdcutHuaWei();
	}
}

public class FractoryPingguo extends Fractory{

	public FractoryPingguo() {
		super("我是苹果工厂");
	}

	@Override
	public Product setProduct() {
		return new ProductPingGuo();
	}
}

每个工厂里面都有自己的名字,并且创建一个对应的产品对象,通过向上转型返回了出去。

5,使用:

public class Go {
	
	public static void main(String[] args) {
		FractoryMi mi = new FractoryMi();
		mi.setProduct().show();
	}
}

结果如下:

我是小米工厂
生产小米手机

通过创建对应的产品工厂,就可以拿到对应的产品对象,然后调用他的shou方法。

优点:

  • 通过常见对应的产品工厂,就能拿到对应的产品对象,同时隐藏了产品被实例化的细节。用户只需要关注工厂,就可以了,不需要知道产品实现的细节。
  • 在创建新产品的时候,只需要增加工厂和创建的产品分别实现对应的抽象类就好了,完全符合 封闭性原则。
  • 创建对象的细节完全封装在具体的工厂内部,而且有了抽象的工厂类,所有的工厂都继承了自己的父类!完美的体现了多态。

缺点;

  • 在增加新的产品时,也必须增加细心地工厂类,会造成额外的开销。
  • 抽象层的加入使得理解起来变得有点困难。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Tʀᴜsᴛ³⁴⁵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值