做网站都可以用什么框架,怎么做自己的单机网站,五站合一自建网站,广东东莞新闻最新消息简介
工厂模式是一种常见的设计模式#xff0c;用于创建对象的过程中#xff0c;通过工厂类来封装对象的创建过程。其核心思想是将对象的创建和使用分离#xff0c;从而降低耦合度#xff0c;提高代码的可维护性和可扩展性。工厂模式通常包括三种类型#xff1a;简单工厂…
简介
工厂模式是一种常见的设计模式用于创建对象的过程中通过工厂类来封装对象的创建过程。其核心思想是将对象的创建和使用分离从而降低耦合度提高代码的可维护性和可扩展性。工厂模式通常包括三种类型简单工厂、工厂方法和抽象工厂。
工厂模式与其他设计模式的主要区别在于它是一种创建型模式用于创建对象的过程中通过工厂类来封装对象的创建过程。与之类似的还有单例模式、建造者模式等。工厂模式主要用于以下两个方面 对象的创建和使用分离将对象的创建过程封装到工厂类中避免了客户端直接依赖具体的产品类从而提高了代码的可维护性和可扩展性。 创建多个产品族或产品等级结构当需要创建多个产品族或产品等级结构时工厂模式可以提供一个统一的接口方便客户端进行调用。 什么是简单工厂模式
简单工厂模式也叫静态工厂模式属于类的创建型模式。提供一个创建对象实例的功能而无须关心其具体实现。被创建实例的类型可以是接口、抽象类也可以是具体的类。
简单工厂模式的本质选择实现 。
设计意图 通过专门定义一个类来负责创建其他类的实例被创建的实例通常都具有共同的父类。
简单工厂模式的结构
简单工厂模式涉及的角色及其职责如下 工厂Factory角色简单工厂模式的核心它负责实现创建所有实例的内部逻辑该类可以被外界直接调用创建所需的产品对象。抽象Product角色简单工厂模式所创建的所有对象的父类它负责约定所有具体产品类所共有的公共接口。具体产品ConcreteProduct角色简单工厂模式所创建的真正实例对象。 以具体代码为例
现在有两种水果苹果(Apple)和香蕉(Banana)为了演示为这两种水果添加一个采集get()方法。
public class Apple{/** 采集*/public void get(){System.out.println(采集苹果);}
}
public class Banana{/** 采集*/public void get(){System.out.println(采集香蕉);}
}
如果要采集水果在不使用任何设计模式的情况下我们一般都会这样做。
public class Client {public static void main(String[] args){//实例化一个AppleApple apple newApple();//实例化一个BananaBanana banana newBanana();apple.get();banana.get();}
}
客户端分别创建苹果和香蕉两个具体产品的实例并调用其采集的方法这样做存在的问题是客户端需要知道所有的具体水果种类即客户端与所有的水果类都存在了耦合关系不符合面向对象设计中的“低耦合”原则。
以上问题如何解决呢答案使用简单工厂利用接口进行“封装隔离”。
Apple和Banana类既然都是水果且共有一个采集的get()方法我们可以为其添加一个父类或让其实现一个共同的接口。在此我们添加一个Fruit接口。
public interface Fruit {/** 采集*/public void get();
}
让Apple和Banana类都实现Fruit接口。
public class Apple implements Fruit{/** 采集*/public void get(){System.out.println(采集苹果);}
}
public class Banana implements Fruit{/** 采集*/public void get(){System.out.println(采集香蕉);}
}
接下来创建一个水果工厂类FruitFactory在工厂中实现对Apple和Banana类的实例化。
public class FruitFactory {/** 获得Apple类的实例*/public static Fruit getApple(){return new Apple();}/** 获得Banana类实例*/public static Fruit getBanana(){return new Banana();}
}
若FruitFactory中getXXX()方法未声明为static的话每次调用方法需创建FruitFactory实例比较麻烦我们直接声明方法为static。
这样我们就能够使用FruitFactory创建Apple和Banana实例对象了。
public class Client{public static void main(String[] args){//实例化一个AppleFruit apple FruitFactory.getApple();Fruit banana FruitFactory.getBanana();apple.get();banana.get();}
}
观察以上工厂其为每一个水果具体类都添加了一个getXXX()方法当水果种类增多时方法数量也会增加导致FruitFactory类比较臃肿而且各个方法之间关系也不够紧密不符合“高内聚”原则我们再对其进行优化。
public class FruitFactory {/** getFruit方法获得所有产品对象*/public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException{if(type.equalsIgnoreCase(apple)) {return Apple.class.newInstance();} elseif(type.equalsIgnoreCase(banana)) {return Banana.class.newInstance();} else{System.out.println(找不到相应的实例化类);return null;}}
}
在客户端使用改良后的FruitFactory来创建Apple和Banana实例对象。
public class Client{public static void main(String[] args){Fruit apple FruitFactory.getFruit(apple);Fruit banana FruitFactory.getFruit(banana);apple.get();banana.get();}
}
运行程序打印结果如下
采集苹果
采集香蕉
什么是工厂方法模式
工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 。工厂方法模式的意义是定义一个创建产品对象的工厂接口将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建这样核心类成为一个抽象工厂角色仅负责声明具体工厂子类必须实现的接口这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
模式中包含的角色及其职责 抽象工厂Factory角色工厂方法模式的核心所有具体工厂类都必须实现这个接口。具体工厂 ConcreteFactory角色具体工厂类是抽象工厂的一个实现负责实例化具体的产品。抽象产品Product角色工厂方法模式所创建的所有具体产品的父类或约定所有具体产品类都应实现的公共接口。具体产品ConcreteProduct角色工厂方法模式所创建的真正对象。 在简单工厂模式中我们了解了简单工厂模式我们使用如下具体的工厂FruitFactory对所有的水果对象进行实例化缺点是显而易见的当有新品种的水果需要产生时就需要修改工厂的getFruit()方法加入新品种水果的逻辑判断和业务代码这极不符合java“开放--封闭”原则。
public class FruitFactory {/** get方法获得所有产品对象*/public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {if(type.equalsIgnoreCase(apple)) {return Apple.class.newInstance();} else if(type.equalsIgnoreCase(banana)) {return Banana.class.newInstance();} /** 如果有新品种的水果需要生产需在此处增加相应逻辑判断及业务代码例如* else if(type.equalsIgnoreCase(pear)) {* return Pear.class.newInstance();* } */else {System.out.println(找不到相应的实例化类);return null;}}
}
接下来我们使用工厂方法模式对以上工厂进行改进首先工厂方法模式中FruitFactory被设计为了抽象工厂(可以是抽象类或者接口),它不再负责具体的产品创建而是将产品的创建工作推迟到了由它的子类来实现接下来以具体的代码为例。
抽象后的FruitFactory仅用来声明其所有子类需实现的接口。
public interface FruitFactory {public Fruit getFruit();
}
有了这个抽象工厂以后假如我们需要苹果了该怎么办很简单创建一个生产苹果的工厂AppleFactory即可。
public class AppleFactory implements FruitFactory{public Fruit getFruit(){return new Apple();}
}
假如我们又需要获取香蕉了该怎么办依旧简单创建一个生产香蕉的工厂BananaFactory即可。
public class BananaFactory implements FruitFactory{public Fruit getFruit(){return new Banana();}
}
如果以后还有其他更多新品种的水果加入只需要创建一个生产相应水果的工厂并让该工厂实现抽象工厂FruitFactory 的接口需要哪种水果我们就调用相应工厂的getFruit()方法得到水果这样做有一个好处无论我们增加多少种水果我们只需增加一个生产相应水果的工厂即可无需对现有的代码进行修改这就很好的符合了开放--封闭原则。开闭原则https://blog.csdn.net/weixin_62458944/article/details/132070314?spm1001.2014.3001.5501
什么是抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的。抽象工厂模式可以向客户端提供一个接口使得客户端在不必指定产品的具体类型的情况下能够创建多个产品族的产品对象。
此处引入了一个新的概念产品族那什么是产品族呢百度一下产品族是以产品平台为基础通过添加不同的个性模块以满足不同客户个性化需求的一组相关产品。 所谓产品族通俗来说即是具有某一共性的一系列相关产品.以前面的Apple(苹果),Banana(香蕉),Pear(梨)为例Apple(苹果),Banana(香蕉),Pear(梨)这三种水果对应上图中的产品等级结构。
这三种水果有产自南方的也有产自北方的北方和南方则对应上图中的产品族产自北方的Apple(苹果),Banana(香蕉),Pear(梨)就构成一个产品族它们的共性是产自北方同样产自南方的Apple(苹果),Banana(香蕉),Pear(梨)也构成了一个产品族。
模式中包含的角色及其职责 抽象工厂Factory角色抽象工厂模式的核心包含对多个产品等级结构的声明任何工厂类都必须实现这个接口。具体工厂ConcreteFactory角色具体工厂类是抽象工厂的一个实现负责实例化某个产品族中的产品对象。抽象Product角色抽象模式所创建的所有对象的父类或声明所有具体产品所共有的公共接口。具体产品ConcreteProduct角色抽象工厂模式所创建的真正实例。 总结抽象工厂中的方法对应产品等级结构具体工厂对应产品族。
接下来用代码进行说明保留之前工厂方法模式中的Fruit接口用来负责描述所有水果实例应该共有的方法。
public interface Fruit {/** 采集*/public void get();
}
此时Apple(苹果)和Banana(香蕉)将不再是具体的产品类而是抽象类因为它们还需要进一步划分北方和南方两个产品族。
public abstract class Apple implements Fruit{/** 采集*/public abstract void get();
}
public abstract class Banana implements Fruit{/** 采集*/public abstract void get();
}
再进一步细分苹果Apple被具体化为北方苹果(NorthApple)和南方苹果(SouthApple)。
public class NorthApple extends Apple {public void get() {System.out.println(采集北方苹果);}}
public class SouthApple extends Apple {public void get() {System.out.println(采集南方苹果);}}
香蕉(Banana)被具体化为北方香蕉(NorthBanana)和南方香蕉(SouthBanana).
public class NorthBanana extends Banana {public void get() {System.out.println(采集北方香蕉);}}
public class SouthBanana extends Banana {public void get() {System.out.println(采集南方香蕉);}}
继续写工厂与之前的FruitFactory有所不同此时的FruitFactory需为每一个产品等级结构添加获取方法声明。
public interface FruitFactory {//实例化Applepublic Fruit getApple();//实例化Bananapublic Fruit getBanana();
}
为每一个产品族添加相应的工厂NorthFruitFactory负责生产所有北方的水果SouthFruitFactory负责生产所有南方的水果。
public class NorthFruitFactory implements FruitFactory {public Fruit getApple() {return new NorthApple();}public Fruit getBanana() {return new NorthBanana();}}
public class SouthFruitFactory implements FruitFactory {public Fruit getApple() {return new SouthApple();}public Fruit getBanana() {return new SouthBanana();}}
在客户端中进行测试代码如下。
public class Client {public static void main(String[] args) {FruitFactory ff1 new NorthFruitFactory();Fruit apple1 ff1.getApple();apple1.get();Fruit banana1 ff1.getBanana();banana1.get();FruitFactory ff2 new SouthFruitFactory();Fruit apple2 ff2.getApple();apple2.get();Fruit banana2 ff2.getBanana();banana2.get();}
}
运行程序打印结果如下
采集北方苹果
采集北方香蕉
采集南方苹果
采集南方香蕉
工厂模式的优缺点
优点 封装对象的创建过程工厂模式将对象的创建过程封装到工厂类中避免了客户端直接依赖具体的产品类从而提高了代码的可维护性和可扩展性。 创建多个产品族或产品等级结构当需要创建多个产品族或产品等级结构时工厂模式可以提供一个统一的接口方便客户端进行调用。 符合开闭原则当需要添加新的产品时只需要增加相应的产品类和工厂方法即可不需要修改原有的代码符合开闭原则。 缺点 增加代码复杂度工厂模式需要增加额外的工厂类增加了代码的复杂度。 增加系统的抽象性和理解难度由于工厂模式引入了抽象层因此增加了系统的抽象性和理解难度。 工厂模式运用场景
工厂模式适用于以下场景 需要创建多个产品族或产品等级结构当需要创建多个产品族或产品等级结构时工厂模式可以提供一个统一的接口方便客户端进行调用。需要封装对象的创建过程当对象的创建过程比较复杂或者需要依赖其他类的时候可以使用工厂模式来封装对象的创建过程。需要动态切换产品当需要动态切换产品时工厂模式可以提供一个统一的接口方便客户端进行调用。 总结
工厂模式是一种常见的设计模式用于创建对象的过程中通过工厂类来封装对象的创建过程。工厂模式具有封装对象的创建过程、创建多个产品族或产品等级结构、符合开闭原则等优点同时也存在增加代码复杂度、增加系统的抽象性和理解难度等缺点。在实际的开发中我们可以根据具体的需求来选择使用工厂模式或其他设计模式。