前言:什么叫设计模式?
设计是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的高内聚和低耦合。
工厂模式
一、定义
解决的就是对象创建的问题,把建立对象实例交给子类来进行。换言之,就是把建立对象实例的过程从正常的业务逻辑中剥离出去,通过抽象来实现。
二、类型
(一)简单工厂
定义:由工厂对象决定创建出哪一种产品类的实例。
适用场景:
1.工厂类负责创建的对象比较少;
2.客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。
优点:
只需要传入一个正确的参数,就可以获取你所需要的对象而无需知道其创建细节。
缺点:
工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则。
代码:
1.创建抽象接口
public interface Juice{
//当前果汁的描述
public void describe();
}
2.创建对应实现类
public class AppleJuice implements Juice {
private static final String TAG = "AppleJuice";
@Override
public void describe() {
Log.i(TAG, "===这是苹果汁===");
}
}
public class OrangeJuice implements Juice{
private static final String TAG = "OrangeJuice";
@Override
public void describe() {
Log.i(TAG, "===这是橙汁===");
}
}
public class GrapeJuice implements Juice{
private static final String TAG = "GrapeJuice";
@Override
public void describe() {
Log.i(TAG, "===这是葡萄汁===");
}
3.创建工厂类
public class JuiceFactory {
public Juice make(String type){
if("apple".equalsIgnoreCase(type)){
return new AppleJuice();
}else if("orange".equalsIgnoreCase(type)){
return new OrangeJuice();
}else if("grape".equalsIgnoreCase(type)){
return new GrapeJuice();
}
return null;
}
}
4.测试代码
public class MyTest {
public static void main(String[] args) {
JuiceFactory juiceFactory = new JuiceFactory();
Juice appleJuice = juiceFactory.make("apple");
appleJuice.describe();
Juice orangeJuice = juiceFactory.make("orange");
orangeJuice.describe();
Juice grapeJuice = juiceFactory.make("grape");
grapeJuice.describe();
}
}
5.执行结果
通过简单工厂类,我们将创建类的具体实现细节隐藏掉了,通过一个工厂类就可以创建多种不同类型的类。但是存在一个问题,那就是创建类的时候不够灵活,每当需要一个全新的类的时候,就会要去修改工厂类中的创建类方法,所以它违背了开闭原则。
简单工厂模式优化:(添加反射)
public class JuiceFactory {
public Juice make(Class clazz){
Juice juice = null;
try{
juice = (Juice)Class.forName(clazz.getName()).newInstance();
}catch(InstantiationException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
return juice;
}
}
通过以上修改,添加新的果汁类型时无需再修改工厂类的代码。
(二)工厂方法
定义:
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。
适用场景:
1.创建对象需要大量重复代码。
2.客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
3.一个类通过其子类来指定创建哪个对象。
优点:
1.用户只需要关心所需产品对应的工厂,无须关心创建细节。
2.加入新产品符合开闭原则,提高可扩展性。
缺点:
增加了类数量。
代码:
1.创建抽象接口
public interface Juice{
//当前果汁的描述
public void describe();
}
2.创建工厂类抽象接口
public abstract class JuiceFactory {
public abstract Juice make();
}
在抽象工厂类中,我们使用的是abstract抽象类,而不是接口,是因为我们在这个类中可能会存在一些已知的方法,而接口类只能定义接口不能实现具体的逻辑,所以此处使用的是抽象类。
3.创建对应的工厂类
public class AppleJuiceFactory extends JuiceFactory{
@Override
public Juice make() {
return new AppleJuice();
}
}
public class OrangeJuiceFactory extends JuiceFactory{
@Override
public Juice make() {
return new OrangeJuice();
}
}
public class GrapeJuiceFactory extends JuiceFactory{
@Override
public Juice make() {
return new GrapeJuice();
}
}
4.测试代码
public class MyTest {
public static void main(String[] args) {
JuiceFactory appleJuiceFactory = new AppleJuiceFactory();
Juice appleJuice = appleJuiceFactory.make();
appleJuice.describe();
JuiceFactory orangeJuiceFactory = new OrangeJuiceFactory();
Juice orangeJuice = orangeJuiceFactory.make();
orangeJuice.describe();
JuiceFactory grapeJuiceFactory = new GrapeJuiceFactory();
Juice grapeJuice = grapeJuiceFactory.make();
grapeJuice.describe();
}
}
5.执行结果
(三)抽象工厂
定义:
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。
适用场景:
1.客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
2.强调一系列相关的产品对象(属于同一产品族)一起适用创建对象需要大量重复的代码。
3.提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
优点:
1.具体的产品在应用层代码隔离,无须关心创建细节。
2.将一系列的产品族统一到一起创建。
缺点:
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
代码:
在工厂方法模式中,一个具体的工厂负责生产一类具体的产品,即一对一的关系,但是,如果需要一个具体的工厂生产多种产品对象,比如,果汁加工厂需要生产铁罐果汁和塑料罐,那么就需要用到抽象工厂模式了。
1.创建抽象接口
public interface Juice{
//当前果汁的描述
public void describe();
}
2.创建铁罐\塑料罐抽象接口
public abstract class TinJuice implements Juice{
public abstract void type();
}
public abstract class PlasticJuice implements Juice{
public abstract void type();
}
3.创建工厂抽象类
public abstract class JuiceFactory {
//做成铁罐
public abstract TinJuice makeTinCans();
//做成塑料罐
public abstract PlasticJuice makePlasticCans();
}
4.创建工厂类对应实现
public class AppleJuiceFactory extends JuiceFactory{
@Override
public TinJuice makeTinCans() {
return new AppleTinJuice();
}
@Override
public PlasticJuice makePlasticCans() {
return new ApplePlasticJuice();
}
}
public class OrangeJuiceFactory extends JuiceFactory{
@Override
public TinJuice makeTinCans() {
return new OrangeTinJuice();
}
@Override
public PlasticJuice makePlasticCans() {
return new OrangePlasticJuice();
}
}
public class GrapeJuiceFactory extends JuiceFactory{
@Override
public TinJuice makeTinCans() {
return new GrapeTinJuice();
}
@Override
public PlasticJuice makePlasticCans() {
return new GrapePlasticJuice();
}
}
5.创建果汁类对应实现
public class AppleTinJuice extends TinJuice {
private static final String TAG = "AppleTinJuice";
@Override
public void type() {
Log.i(TAG, "===打包进铁罐===");
}
@Override
public void describe() {
Log.i(TAG, "===这是苹果汁===");
}
}
public class ApplePlasticJuice extends PlasticJuice {
private static final String TAG = "ApplePlasticJuice";
@Override
public void type() {
Log.i(TAG, "===打包进塑料罐===");
}
@Override
public void describe() {
Log.i(TAG, "===这是苹果汁===");
}
}
…其余两种类型同理…
6.测试代码
public class MyTest {
public static void main(String[] args) {
//创建苹果加工厂
JuiceFactory appleJuiceFactory = new AppleJuiceFactory();
//生产铁罐苹果汁
TinJuice appleTinJuice = appleJuiceFactory.makeTinCans();
appleTinJuice.type();
appleTinJuice.describe();
//生产塑料罐苹果汁
PlasticJuice applePlasticJuice = appleJuiceFactory.makePlasticCans();
applePlasticJuice.type();
applePlasticJuice.describe();
//创建橙汁加工厂
JuiceFactory orangeJuiceFactory = new OrangeJuiceFactory();
//生产铁罐橙汁
TinJuice orangeTinJuice = orangeJuiceFactory.makeTinCans();
orangeTinJuice.type();
orangeTinJuice.describe();
//生产塑料罐橙汁
PlasticJuice orangePlasticJuice = orangeJuiceFactory.makePlasticCans();
orangePlasticJuice.type();
orangePlasticJuice.describe();
//创建葡萄汁加工厂
JuiceFactory grapeJuiceFactory = new GrapeJuiceFactory();
//生产铁罐葡萄汁
TinJuice grapeTinJuice = grapeJuiceFactory.makeTinCans();
grapeTinJuice.type();
grapeTinJuice.describe();
//生产塑料罐葡萄汁
PlasticJuice grapePlasticJuice = grapeJuiceFactory.makePlasticCans();
grapePlasticJuice.type();
grapePlasticJuice.describe();
}
}
7.执行结果