首页 > 编程语言 >JAVA设计模式之工厂模式

JAVA设计模式之工厂模式

时间:2023-07-03 15:36:19浏览次数:49  
标签:JAVA void 模式 工厂 Phone return 设计模式 public

设计模式

设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

六大原则:

单一职责原则:
不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,否则就应该把类拆分

里氏替换原则(Liskov Substitution Principle):
子类可以扩展父类的功能,但不能改变父类原有的功能。父类能出现的地方都可以用子类来代替,而且换成子类也不会出现任何错误或异常,而使用者也无需知道是父类还是子类,但反过来则不成立。总之,就是抽象。

依赖倒转原则(Dependence Inversion Principle):
面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互

接口隔离原则(Interface Segregation Principle):
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。

迪米特法则(最少知道原则)(Demeter Principle):
一个类对自己依赖的类知道的越少越好。无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。

合成复用原则(Composite Reuse Principle):
尽量首先使用合成/聚合的方式,而不是使用继承。

工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。工厂模式有两种,一种是单一工厂,即用一个工厂就可以根据业务创建出不同的产品对象,又称简单工厂模式;另一种是多个工厂,每个工厂对应一个产品对象,又称工厂方法模式。

简单工厂模式

思想:根据业务需求,将所需要的产品‘告诉’工厂,由工厂去创建对象。

 产品接口

public interface Phone {
    public void getColor();
}

具体产品

public class Honor implements Phone {
    @Override
    public void getColor() {
        System.out.println("White");
    }
}
public class Huawei implements Phone {
    @Override
    public void getColor() {
        System.out.println("Black");
    }
}

产品工厂

public class PhoneFactory {
    public static Phone getPhone(String kind) {
        switch (kind) {
            case "Huawei":
                return new Huawei();
            case "Honor":
                return new Honor();
            default:
                return null;
        }
    }
}

测试

    public static void main(String[] args) {
        PhoneFactory factory = new PhoneFactory();
        Phone huawei = factory.getPhone("Huawei");
        huawei.getColor();
        Phone honor = factory.getPhone("Honor");
        honor.getColor();
    }
  • 优点:调用者只需要调用一个工厂对象,把创建对象的动作交给工厂,调用者不需要关心创建过程,只需要根据不同需求传递产品类型就创建出不同产品,降低了系统的耦合性。
  • 缺点:工厂管理所有对象的创建,每次新增一个产品,都需要改动工厂对象,长此以往工厂对象里管理的产品会越来越多越来越臃肿。

工厂方法模式

 思想:创建多个工厂对象,每个工厂对象对应一个产品。

产品接口

public interface Phone {
    public void getColor();
}

具体产品

public class Huawei implements Phone {
    @Override
    public void getColor() {
        System.out.println("Black");
    }
}
public class Honor implements Phone {
    @Override
    public void getColor() {
        System.out.println("White");
    }
}

产品工厂接口

public interface PhoneFactory {
    public Phone getPhone();
}

具体工厂

public class HuaweiFactory implements PhoneFactory {
    @Override
    public Phone getPhone() {
        return new Huawei();
    }
}
public class HonorFactory implements PhoneFactory {
    @Override
    public Phone getPhone() {
        return new Honor();
    }
}

测试

    public static void main(String[] args) {
        PhoneFactory huaweiFactory = new HuaweiFactory();
        Phone huawei = huaweiFactory.getPhone();
        huawei.getColor();
        PhoneFactory honorFactory = new HonorFactory();
        Phone honor = honorFactory.getPhone();
        honor.getColor();
    }
  • 优点:在简单工厂的基础上提高了扩展性,新增产品时不要改原来的代码,只需创建产品和和产品工厂。
  • 缺点:工厂和产品的耦合性高这就导致新增产品时就必须得新增产品工厂,增加了系统的复杂性。

抽象工厂模式

抽象工厂是对工厂方法模式的扩展,属于技术方面的升级。将工厂进行抽象化,让每个工厂只负责一个’系列‘的产品对象的创建,大大提高了系统的扩展性和实用性,同时也提高了复杂性!

产品接口

产品一:手机

public interface Phone {
    public void getColor();
}

产品二:电脑

public interface Computer {
    public void getPrice();
}

具体产品

产品一:手机

public class Huawei implements Phone {
    @Override
    public void getColor() {
        System.out.println("Black Huawei");
    }
}
public class Honor implements Phone {
    @Override
    public void getColor() {
        System.out.println("White Honor");
    }
}

产品二:电脑

public class MacBook implements Computer {
    @Override
    public void getPrice() {
        System.out.println("MacBook 15999");
    }
}
public class MateBook implements Computer {
    @Override
    public void getPrice() {
        System.out.println("MateBook 11999");
    }
}

工厂接口

public interface AbstractFactory {
    public Phone getPhone(String phone);
    public Computer getComputer(String computer);
}

具体工厂

工厂一:手机工厂

public class PhoneFactory implements AbstractFactory {
    @Override
    public Phone getPhone(String phone) {
        switch (phone) {
            case "huawei":
                return new Huawei();
            case "honor":
                return new Honor();
            default:
                return null;
        }
    }

    @Override
    public Computer getComputer(String computer) {
        return null;
    }
}

工厂二:电脑工厂

public class ComputerFactory implements AbstractFactory {
    @Override
    public Phone getPhone(String phone) {
        return null;
    }

    @Override
    public Computer getComputer(String computer) {
        switch (computer) {
            case "mac":
                return new MacBook();
            case "mate":
                return new MateBook();
            default:
                return null;
        }
    }
}

工厂选择器(这一步可有可无,实际业务中也可以直接创建工厂对象)

public class FactorySelector {
    AbstractFactory getFactory(String factory) {
        switch (factory) {
            case "phone":
                return new PhoneFactory();
            case "computer":
                return new ComputerFactory();
            default:
                return null;
        }
    }
}

测试

    public static void main(String[] args) {
        FactorySelector factorySelector = new FactorySelector();
        
        AbstractFactory phoneFactory = factorySelector.getFactory("phone");
        Phone huawei = phoneFactory.getPhone("huawei");
        huawei.getColor();
        Phone honor = phoneFactory.getPhone("honor");
        honor.getColor();
        
        AbstractFactory computerFactory = factorySelector.getFactory("computer");
        Computer macBook = computerFactory.getComputer("mac");
        macBook.getPrice();
        Computer mateBook = computerFactory.getComputer("mate");
        mateBook.getPrice();
    }
  • 优点:把工厂抽象化可以进一步的减少调用者和产品对象的耦合性,用户只需要根据需求去调用指定的工厂即可。
  • 缺点:从代码量上也可以看出来,系统更加复杂了,增加代码维护的困难性。

补充:看起来抽象工厂好像比工厂方法增加了很多代码,好像只是把生产工厂给包一层,有点画蛇添足。实际上要考虑到实际业务场景:很多产品不仅仅只有一个属性或者一个方法,有个对象会有很多功能,甚至涉及到其他对象,那么在设计项目框架时如果可以把相同属性的产品对象归属到一个系列,然后指定一个工厂去管理这个系列,这样就可以更好的去实现相应的业务。然后再把工厂给抽象化,让特定的需求去调用特定的工厂,这样无论是自己写代码还是别人根据代码去分析功能时都会思路非常清晰。

总结:

虽然说简单工厂模式是工厂模式的初版,工厂方法和抽象工厂模式对简单工厂都有了一定的扩展和加强,但是并不是说抽象工厂模式就是最好的,三者都有优缺点。代码是死的,人是活的,要根据实际业务场景去选择最匹配的模式!

 

标签:JAVA,void,模式,工厂,Phone,return,设计模式,public
From: https://www.cnblogs.com/Bernard94/p/17522077.html

相关文章

  • 在Java中使用Apache POI导入Excel文件并保留内容的换行符
    importorg.apache.poi.ss.usermodel.*;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importjava.io.FileInputStream;importjava.io.IOException;publicclassReadExcelWithNewlines{publicstaticvoidmain(String[]args){StringfilePat......
  • 电脑迷宫鼠(Java语言实现)
    电脑迷宫鼠基础要求1.概述:用java面向对象程序设计语言,设计和实现一电脑鼠走迷宫的软件程序,即一个假想的小车能在图示的迷宫中根据设定的起始点和终点自主寻找路径。本综合实践分成两部分:第一部分为算法设计和实现部分,第二部分为界面展现部分。2.第一部......
  • 画出结构型设计模式的类图
    装饰器模式Decorator适配器模式Adapter桥接模式Bridge组合模式Composite代理模式Proxy静态代理JDK动态代理享元模式Flyweight外观模式Facade ......
  • java8发送邮件失败, 修改jdk镜像中的java.security文件
    背景原本部署环境中的java:8镜像在检查问题删除,用dockerpullopenjdk:8重新拉取并改名java:8,在重新部署后,发送邮件报错:javax.net.ssl.SSLHandshakeException:Noappropriateprotocol(protocolisdisabledorciphersuitesareinappropriate)!!!原因根本原因是j......
  • Java线程池基础介绍
    一、线程池的优点1、线程池能够复用已经创建了的线程来执行任务,从而降低了频繁创建和销毁线程所带来的资源消耗;2、任务创建完成时,不必等待线程的创建,能够立即执行,提高了任务响应的速度。 二、创建线程池的七大核心参数1、corePoorSize核心线程数线......
  • JavaScript 中 object 的几个方法:entries,values,keys 对比
    在JavaScript中,对象(Object)是一种无序的键值对集合。以下是entries,values和keys这三个对象方法的比较: entries()方法:返回一个包含对象的键值对的数组。每个键值对都是一个数组,包含两个元素,第一个元素是键名,第二个元素是对应的值。1constobj={a:1,b:2,c:3};2conso......
  • JAVA获取字符串内的括号对(支持多层级);获取括号对的内容;按指定规则返回括号对位置;
    先看结果:处理字符串 "这个是一条测试用的字符串[(5(4(3[(1)(2)]))(7))][(6)]"结果  解决思路:参考正则表达式里面出入站部分 代码实现如下:方法调用“: Stringtest="这个是一条测试用的字符串[(5(4(3[(1)(2)]))(7))][(6)]";LinkedHashMap<Inte......
  • 41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】
    已经好久没有讲一些基础的知识了,这一小节来点简单的,这也是为下节的在Spring多数Boot中使用多数据源做准备。从Spring3.0开始,增加了一种新的途径来配置BeanDefinition,这就是通过JavaCode配置BeanDefinition。      与XML和Annotation两种配置方式不同点在于:      ......
  • 郑州Java面试题
    常见题库https://github.com/cosen1024/Java-Interviewhttps://github.com/whx123/JavaHomehttps://github.com/lvminghui/Java-Noteshttps://github.com/cosen1024/Java-Interview==和equals区别==基本类型比较的是值,对象类型比较的是地址,equals默认情况下也是比较地址......
  • JAVA生成xml文件格式
    publicboolean A(参数1,……){Documentdocument=DocumentHelper.createDocument();Namespacena=Namespace.get("");Strings=null;na=new Namespace(xxxxxxxxxxxxxxxxxxxxx);//命名空间Elementroot=document.addElement(newQName(“A......