1.什么是工厂设计模式,为什么需要工厂设计模式
工厂设计模式:需要一个东西,你不需要自己去手动制造,而是交给工厂去制造,你去工厂里面取你所需要的东西。比如:需要用到一个对象,你不需要手动去new,而是去工厂中获取,有工厂来创建这个对象。
好处:解耦,减少冗余,提高容错
解耦:假如一个A类需要B类,A类只需要关注你所调用的方法,至于B类的创建A类不需要关心,只需要去从工厂中获取即可
减少冗余:假如一个类的创建特别复杂,每次使用都要自己创建一遍,会产生大量的冗余代码,工厂提供了统一的创建对象的方法,从一定程度上减少了冗余代码
提高容错性:如果自己需要一个类自己每次都要手动创建,有可能某一次创建代码会出现问题,工厂规避了这个问题
简单工厂(静态工厂)
/**
* 产品牛奶 接口定义
*/
public interface IMilk{
void product();
}
public class JinDianMilk implements IMilk{
@Override
public void product(){
System.out.println("this is Jing Dian milk");
}
}
public class MengNiuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is meng niu milk");
}
}
public class TelunSuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is tls milk");
}
}
public class SimpleFactory{
public static finalintJD =1;
public static finalintMN =2;
public static finalintTLS =3;
public static IMilk creatMilk(int i){
switch(i){
case1:returnnewJinDianMilk();
case2:returnnewMengNiuMilk();
case3:returnnewTelunSuMilk();
default:System.out.println("no such milk");
}
return null;
}
}
/**
* 简单工厂设计模式
* 可以是实现工厂的要求 一个工厂可以生产出不同产品来
* 但是 这种方式耦合性高 假如需要再加一种产品 需要修改代码逻辑
* 违背了 开闭原则
* 耦合度高 扩展性差
*/
public class SimpleFactoryMain{
public static void main(String[] args){
IMilk jdMilk = SimpleFactory.creatMilk(SimpleFactory.JD);
jdMilk.product();
IMilk mnMilk = SimpleFactory.creatMilk(SimpleFactory.MN);
mnMilk.product();
}
}
工厂方法模式
/**
* 产品牛奶 接口定义
*/
public interface IMilk{
void product();
}
/**
* 工厂接口
*/
public interface IFactory{
IMilk create();
}
/**
* 产品类 -- 经典
*/
public class JinDianMilk implements IMilk{
@Override
public void product(){
System.out.println("this is Jing Dian milk");
}
}
/**
* 生产经典牛奶的工厂
*/
public class JinDianFactory implements IFactory{
@Override
public IMilk create(){
return new JinDianMilk();
}
}
/**
* 产品类(蒙牛)
*/
public class MengNiuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is meng niu milk");
}
}
/**
* 生产蒙牛的工厂
*/
public class MengNiuFactory implements IFactory{
@Override
public IMilk create(){
return new MengNiuMilk();
}
}
/**
* 产品类 -- 特仑苏
*/
public class TelunSuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is tls milk");
}
}
/**
* 生产特仑苏的工厂
*/
public class TelunSuFactory implements IFactory{
@Override
public IMilk create(){
return new TelunSuMilk();
}
}
/**
* 工厂方法模式
* 这个种模式 工厂做到了抽象化 每加一种产品
* 可以动态的扩展工厂 不需要修改之前的业务逻辑代码
* 相比简单工厂模式 代码变得灵活了 符合了开闭原则
* <p>
* 缺点: 这种方式 随着产品种类的增加 会出现大量
* 与之对应的工厂对象 工程会显得很臃肿
*/
public class FactoryMethod{
public static void main(String[] args){
IFactory jinDianFactory =newJinDianFactory();
IFactory mengNiuFactory =newMengNiuFactory();
IFactory telunSuFactory =newTelunSuFactory();
IMilk iMilk = jinDianFactory.create();
iMilk.product();
IMilk iMilk1 = mengNiuFactory.create();
iMilk1.product();
IMilk iMilk2 = telunSuFactory.create();
iMilk2.product();
}
}
抽象工厂
/**
* 产品牛奶 接口定义
*/
public interface IMilk{
void product();
}
/**
* 抽象工厂
*/
public abstract class IFactory{
abstract IMilk createJDMilk();
abstract IMilk createMnMilk();
abstract IMilk createTlsMilk();
}
/**
* 经典牛奶 产品类
*/
public class JinDianMilk implements IMilk{
@Override
public void product(){
System.out.println("this is Jing Dian milk");
}
}
/**
* 蒙牛 产品类
*/
public class MengNiuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is meng niu milk");
}
}
/**
* 特仑苏 产品类
*/
public class TelunSuMilk implements IMilk{
@Override
public void product(){
System.out.println("this is tls milk");
}
}
/**
* 工厂的实现
*/
public class Factory extends IFactory{
@Override
IMilk createJDMilk(){
return new JinDianMilk();
}
@Override
IMilk createMnMilk(){
return new MengNiuMilk();
}
@Override
IMilk createTlsMilk(){
return new TelunSuMilk();
}
}
/**
* 抽象工厂模式是工厂方法模式的进一步延伸,由于它提供了功能更为强大的工厂类并且具备较好的可扩展性,
* 在软件开发中得以广泛应用,尤其是在一些框架和API类库的设计中,
* 例如在Java语言的AWT(抽象窗口工具包)中就使用了抽象工厂模式,
* 它使用抽象工厂模式来实现在不同的操作系统中应用程序呈现与所在操作系统一致的外观界面。
* 抽象工厂模式也是在软件开发中最常用的设计模式之一。
*
* 1. 主要优点
* (1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,
* 更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,
* 因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
* (2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
* (3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
* 2. 主要缺点
* 抽象工厂模式的主要缺点如下:
* 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,
* 违背了“开闭原则”。
* 适用场景摘录:
* (1) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,
* 这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
* (2) 系统中有多于一个的产品族,而每次只使用其中某一产品族。
* 可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
* (3) 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
* 同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束,
* 如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,
* 此时具有一个共同的约束条件:操作系统的类型。
* (4) 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
*
*
*/
public class AbstractFactoryMain{
public static void main(String[] args){
Factory factory =newFactory();
IMilk jdMilk = factory.createJDMilk();
jdMilk.product();
IMilk mnMilk = factory.createMnMilk();
mnMilk.product();
IMilk tlsMilk = factory.createTlsMilk();
tlsMilk.product();
}
}