设计模式——工厂设计模式和适配器设计模式
Posted dch-21
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——工厂设计模式和适配器设计模式相关的知识,希望对你有一定的参考价值。
工厂设计模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
设计目的
工厂设计模式,是一种创建型设计模式。是为了获取某一个对象而存在的设计模式。
有时候,我们在获取对象的时候,会根据不同的条件,获取不同的对象。或者,有时候,我们需要对所有的对象的获取后,进行相同的初始化的操作。此时,就可以使用工厂设计模式,来进行对象的获取的处理。
简单工厂模式
主要是来解决一个类的不同子类对象的获取。可以设计一个工厂类,按照用户不同的需求,实例化不同的子类对象,并经过向上转型,返回给用户。这种设计模式,就是简单工厂设计模式。
其实,简单工厂设计模式,就是把对象的获取做了一次封装。而简单工厂中的工厂方法,一般情况下,为了方便调用,会设计为静态方法。但是,从逻辑上出发,设计为非静态方法才更合适。
优点:
-
代码简单、逻辑简单。适合处理一些简单的业务需求,无法处理产品族的问题。
缺点: -
简单工厂模式,不符合设计模式的基本原则———开闭原则。
开闭原则:对拓展开放,对修改关闭。在进行功能拓展的时候,不要对现有的逻辑进行改动,只需要进行拓展的模块的添加即可。
但是,简单工厂模式中,这个工厂类中,将所有的对象的获取都封装进来了,用户只需要传入一个需求,就可以获取到一个对象。但是,这样一来,这里的工厂方法,就会非常复杂。这样的类,被称为“上帝类”。所有的逻辑都在这里处理,会导致这里的业务逻辑比较庞大,不利于维护。
同时,如果需要进行功能拓展,势必需要修改这个工厂方法,添加新的逻辑。这样,就违背开闭原则。
- 简单工厂模式, 由于处理逻辑过于简单, 无法处理产品族的问题。
产品族:某些品牌产品旗下可能有不同种类的子产品。例如:苹果。苹果旗下不止生产手机,还有电脑、平板...
/**
* @Author 昊
* @Create 2020/5/8 21:41
* @Description 简单工厂模式
*/
public class SimpleFactoryTest {
public static void main(String[] args) {
Phone huawei=new PhoneFactory().getPhone("华为");
Phone xiaomi=new PhoneFactory().getPhone("小米");
Phone apple=new PhoneFactory().getPhone("苹果");
}
}
class Phone { }
class ApplePhone extends Phone{}
class HuaweiPhone extends Phone{}
class XiaomiPhone extends Phone{}
class PhoneFactory{
public Phone getPhone(String name){
if(name.equalsIgnoreCase("华为")){
System.out.println("华为手机一台");
return new HuaweiPhone();
}else if(name.equalsIgnoreCase("小米")){
System.out.println("小米手机一台");
return new XiaomiPhone();
}else if(name.equalsIgnoreCase("苹果")){
System.out.println("苹果手机一台");
return new ApplePhone();
}
return null;
}
}
工厂方法模式
简单工厂模式中,违背了“开闭原则”。为了解决这个问题,需要将“上帝类”进行拆分,把不同的需求,分到不同的类中去执行。可以设计多个工厂,每一个工厂,负责一种产品的获取。此时在遇到需求变更的时候,只需要修改指定的工厂即可,不需要对其他的工厂进行改动。而且,在遇到新增需求的时候,只需要添加对应的工厂即可,不需要对现有的任意的工厂进行改动。
实际上,工厂方法模式,是从简单工厂模式到抽象工厂模式之间的一个过渡。工厂方法模式,也可以理解为抽象工厂模式的一个极端案例(如果某一个产品的产品族中只有一种产品,此时抽象工厂,就是工厂方法模式)。
优点
- 相比较于简单工厂模式,工厂方法模式是遵循开闭原则的。
缺点 - 依然无法处理产品族的问题。
/**
* @Author 昊
* @Create 2020/5/8 22:06
* @Description 工厂方法模式
*/
public class factoryMethodTest {
public static void main(String[] args) {
HuaweiPhone huaweiPhone=new HuaweiFactor().getPhone();
XiaomiPhone xiaomiPhone=new XiaomiFactory().getPhone();
ApplePhone applePhone=new AppleFactory().getPhone();
}
}
class Phone { }
class HuaweiPhone extends Phone{}
class XiaomiPhone extends Phone{}
class ApplePhone extends Phone{}
abstract class Factory {
public abstract Phone getPhone();
}
class HuaweiFactor extends Factory{
@Override
public HuaweiPhone getPhone() {
System.out.println("华为手机工厂");
return new HuaweiPhone();
}
}
class XiaomiFactory extends Factory{
@Override
public XiaomiPhone getPhone() {
System.out.println("小米手机工厂");
return new XiaomiPhone();
}
}
class AppleFactory extends Factory{
@Override
public ApplePhone getPhone() {
System.out.println("苹果厂");
return new ApplePhone();
}
}
抽象工厂模式
抽象工厂模式,是为了解决一个品牌下不同的产品族的问题的。其实,抽象工厂,并没有多么的“抽象”。抽象工厂模式,比简单工厂和工厂方法模式要稍微的复杂,但是通用性更强。
手机 | 平板 | 电脑 | |
---|---|---|---|
华为 | 华为手机 | 华为平板 | 华为电脑 |
小米 | 小米手机 | 小米平板 | 小米电脑 |
苹果 | 苹果手机 | 苹果平板 | 苹果电脑 |
/**
* @Author 昊
* @Create 2020/5/8 22:17
* @Description 抽象工厂模式
* 将品牌设置成类
* 将设备设置成接口
*/
public class AbastractFactoryTest {
public static void main(String[] args) {
XiaomiPad xiaomiPad=new XiaomiFactory().getPad();
HuaweiPhone huaweiPhone=new HuaweiFactory().getPhone();
}
}
class Xiaomi{}
class Huawei{}
class Apple{}
interface Phone{}
interface Pad{}
interface Computer{}
class HuaweiPhone extends Huawei implements Phone{}
class HuaweiPad extends Huawei implements Pad{}
class HuaweiComputer extends Huawei implements Computer{}
class XiaomiPhone extends Xiaomi implements Phone{}
class XiaomiPad extends Xiaomi implements Pad{}
class XiaomiComputer extends Xiaomi implements Computer{}
class ApplePhone extends Apple implements Phone{}
class iPad extends Apple implements Pad{}
class AppleComputer extends Apple implements Computer{}
abstract class Factory {
public Phone getPhone(){
return null;
}
public Pad getPad (){
return null;
}
public Computer getComputer(){
return null;
}
}
class HuaweiFactory extends Factory{
@Override
public HuaweiPhone getPhone() {
System.out.println("华为手机");
return new HuaweiPhone();
}
@Override
public HuaweiPad getPad() {
System.out.println("华为平板");
return new HuaweiPad();
}
@Override
public HuaweiComputer getComputer() {
System.out.println("华为电脑");
return new HuaweiComputer();
}
}
class XiaomiFactory extends Factory{
@Override
public XiaomiPhone getPhone() {
return new XiaomiPhone();
}
@Override
public XiaomiPad getPad() {
return new XiaomiPad();
}
@Override
public XiaomiComputer getComputer() {
return new XiaomiComputer ();
}
}
class AppleFactory extends Factory{
@Override
public ApplePhone getPhone() {
return new ApplePhone();
}
@Override
public iPad getPad() {
return new iPad();
}
@Override
public AppleComputer getComputer() {
return new AppleComputer();
}
}
适配器设计模式
有些时候,我们要使用到的功能,在其他的模块中已经完成了。但是当我们直接使用这个已经实现的功能模块的时候,已经实现的这个模块和我们现在需要使用到的模块之间有接口不兼容的问题。此时,我们没有办法直接使用这个已经实现的模块。
电源适配器:每一个手机、电脑都有电源适配器,可以将220V的交流电适配成电脑、手机可以承受的范围,可以直接使用的范围。
手机适配器:电脑上都有USB接口,可以直接连接一些USB的外设设备,例如:U盘、鼠标、键盘、硬盘...。但是,有些时候,我们需要将手机连接到电脑上。此时,手机是不能直接连接到电脑上的,因为手机和电脑直接是接口不兼容的。Lighting
适配器模式,将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
实现方式将自己的接口包裹在一个已经存在的类中。
/**
* @Author 昊
* @Create 2020/5/8 22:44
* @Description
*/
public class AdapterTest {
public static void main(String[] args) {
Computer computer=new Computer();
computer.setUsb1(new Mouse());
computer.setUsb2(new Adapter(new Phone()));
computer.show();
}
}
class Computer {
private USB usb1;
private USB usb2;
public void setUsb1(USB usb1) {
this.usb1 = usb1;
}
public void setUsb2(USB usb2) {
this.usb2 = usb2;
}
public void show(){
System.out.println("USB1连接了"+this.usb1.getUSBDeviceInfo());
System.out.println("USB2连接了"+this.usb2.getUSBDeviceInfo());
}
}
//手机支持的接口,与USB不同
interface Lighting {
//获取设备信息,汇报给适配器
String getLightingDeviceInfo();
}
//USB接口,提供了连接到电脑的设备的统一规范
interface USB{
// 获取一个USB设备的描述信息,汇报给电脑
String getUSBDeviceInfo();
}
//鼠标类,是一个USB接口的实现类,可以直接通过USB接口连接到电脑上
class Mouse implements USB{
@Override
public String getUSBDeviceInfo() {
return "鼠标";
}
}
//手机,是一个Lighting接口的实现类
class Phone implements Lighting{
@Override
public String getLightingDeviceInfo() {
return "realmeX";
}
}
//实现了 USB-Lighting 的转换
class Adapter implements USB{
private Lighting lighting;
public Adapter(Lighting lighting){
this.lighting=lighting;
}
@Override
public String getUSBDeviceInfo() {
return this.lighting.getLightingDeviceInfo();
}
}
以上是关于设计模式——工厂设计模式和适配器设计模式的主要内容,如果未能解决你的问题,请参考以下文章