视频下载软件,百度seo优化包含哪几项,可以做机械设计接单的网站,商业运营是做什么的创建型设计模式-2.工厂设计模式
一、示例代码
下面是一个没有使用工厂设计模式的例子#xff0c;ResourceLoader 类负责根据 URL 的前缀来加载资源。根据不同的前缀#xff0c;它执行不同的操作来创建 Resource 对象。这导致了以下问题#xff1a;
代码冗余#xff1a;在…创建型设计模式-2.工厂设计模式
一、示例代码
下面是一个没有使用工厂设计模式的例子ResourceLoader 类负责根据 URL 的前缀来加载资源。根据不同的前缀它执行不同的操作来创建 Resource 对象。这导致了以下问题
代码冗余在每个分支中都有相似的复杂操作用于创建 Resource 对象这造成了代码的重复。可扩展性差当需要添加新的资源类型时需要修改 ResourceLoader 类的代码并增加对应的分支。这违反了开闭原则使代码难以扩展和维护。低内聚性ResourceLoader 类的职责既包括根据前缀选择创建资源对象的逻辑又包括资源对象的创建过程导致职责不够单一。
没有使用工厂设计模式的代码实现不够灵活代码复用性较低并且随着业务需求的变化代码的维护和扩展会变得困难。相比之下使用工厂设计模式可以将对象的创建逻辑封装到工厂类中提高了代码的可扩展性和可维护性同时使得代码更加清晰和易于理解。
public class Resource {private String url;public Resource(String url) {this.url url;}
}public class ResourceLoader {private Resource load(String url) {// 根据前缀匹配String prefix getPrefix(url);if (prefix.equals(http)) {// 很复杂的操作可能此处会执行很久return new Resource(url);} else if (prefix.equals(file)) {// 很复杂的操作可能此处会执行很久return new Resource(url);} else if (prefix.equals(classpath)) {// 很复杂的操作可能此处会执行很久return new Resource(url);} else {return new Resource(default);}}private String getPrefix(String url) {if (url null || .equals(url) || url.contains(:)) {throw new ResourceLoadException(url不合法);}String[] split url.split(:);return split[0];}
}上述代码包含两个类Resource 和 ResourceLoader。
Resource 类表示资源对象具有一个私有的 url 字段和一个公共的构造函数。它通过构造函数接收一个 url 参数并将其赋值给 url 字段。ResourceLoader 类是一个资源加载器它有一个私有的 load 方法用于加载资源。该方法接收一个 url 参数根据其前缀进行匹配。根据前缀的不同它执行不同的操作来创建并返回一个 Resource 对象。 在 load 方法中它通过调用私有的 getPrefix 方法来获取 url 的前缀。然后使用条件语句判断前缀是什么并在每个分支中执行复杂的操作可能需要执行很久来创建一个对应的 Resource 对象。如果前缀不匹配任何条件则创建一个默认的 Resource 对象。getPrefix 方法用于从 url 中提取前缀。它首先检查 url 是否为空、空字符串或包含冒号。如果是则抛出一个 ResourceLoadException 异常表示 url 不合法。否则它通过将 url 使用冒号进行分割并返回分割后的第一个元素作为前缀。
总结以上代码展示了一个简单的资源加载器根据给定的 url 和其前缀创建并返回对应的 Resource 对象。它通过条件语句进行判断和创建没有使用工厂设计模式。然而这种实现方式存在代码冗余和可扩展性差的问题。工厂设计模式可以用来改善这些问题。 二、简单工厂
总结就是一个工厂负责生产多个产品
1.简介
简单工厂设计模式Simple Factory Pattern是一种创建型设计模式旨在通过一个工厂类来封装对象的创建过程。它属于最基本的工厂模式虽然并不是一种正式的设计模式但在实际开发中被广泛应用。
在简单工厂模式中存在一个具体的工厂类负责根据客户端的需求创建不同类型的产品对象。客户端只需要提供一个参数或条件给工厂类工厂类根据参数或条件的不同返回相应类型的产品对象。这样客户端与具体产品类之间解耦不需要直接依赖具体产品的创建过程。
2.案例
public class ResourceLoadFactory {public static Resource create(String type, String url) {if (type.equals(http)) {//很复杂的操作,可能此处会执行很久return new Resource(url);} else if (type.equals(file)) {//很复杂的操作,可能此处会执行很久return new Resource(url);} else if (type.equals(classpath)) {//很复杂的操作,可能此处会执行很久return new Resource(url);} else {return new Resource(default);}}
}其中ResourceLoadFactory充当了工厂类的角色create方法充当了工厂方法。根据传入的type参数create方法决定实例化并返回不同类型的Resource对象。
简单工厂模式的优点之一是将对象的创建过程集中在一个工厂类中使得客户端代码与具体的对象创建逻辑解耦。客户端只需要调用工厂方法并传入相应的参数即可获得所需的对象实例而无需了解对象的具体创建细节。
3.总结
简单工厂设计模式的优点 封装对象的创建过程简单工厂模式将对象的创建逻辑封装在工厂类中客户端只需调用工厂方法而无需了解对象的具体创建过程。 解耦客户端和具体对象客户端代码只与工厂类打交道无需直接与具体对象类交互从而实现了客户端代码与具体对象的解耦。 简化客户端代码客户端只需调用工厂方法并传入相应参数即可获得所需对象的实例无需自行创建对象从而简化了客户端代码。
简单工厂设计模式的缺点 不符合开闭原则当需要添加新的产品类型时需要修改工厂类的代码违反了开闭原则。这可能导致工厂类的代码过于复杂且对于每个新的产品类型的添加都需要修改工厂类增加了代码的维护成本。 可能过于臃肿随着产品类型的增加工厂类可能变得庞大而臃肿对于复杂的产品类型结构简单工厂模式可能无法很好地管理和创建对象。 不支持扩展性由于工厂类集中了所有对象的创建逻辑如果需要对不同类型的对象采取不同的创建逻辑则无法通过简单工厂模式实现。
总结简单工厂模式适用于创建对象的过程相对简单且不频繁变化的情况。它提供了一种简单的对象创建方式使得客户端代码与具体对象的创建逻辑解耦。然而它的缺点是不符合开闭原则难以扩展和维护。在面对复杂的对象结构和频繁变化的创建逻辑时可以考虑使用其他更灵活的创建型设计模式。
三、工厂方法
总结就是一个工厂生产一个产品
1.简介
工厂方法设计模式Factory Method Pattern是一种创建型设计模式用于解决对象的创建问题。它将对象的创建延迟到子类中通过定义一个创建对象的接口让子类决定实例化哪个具体类。
**核心思想是将对象的实例化交给子类来完成而不是在父类中直接创建对象。**这样可以将对象的创建与使用分离提高代码的灵活性和可扩展性。
工厂方法模式通常包含以下角色 抽象产品Abstract Product定义产品的共同接口或抽象类具体产品需要实现这个接口或继承这个抽象类。 具体产品Concrete Product实现抽象产品接口或继承抽象产品类是工厂方法所创建的对象实例。 抽象工厂Abstract Factory定义创建产品的接口包含创建产品的抽象方法。 具体工厂Concrete Factory实现抽象工厂接口实现创建具体产品的方法。
工厂方法模式通过引入抽象工厂和具体工厂来解决直接实例化具体产品的问题。客户端代码只需要与抽象工厂进行交互而不需要直接与具体产品类打交道。具体的产品对象由具体工厂类来创建具体工厂类的选择由客户端来决定。
2.案例 抽象产品和具体产品 Data
public abstract class AbstractResource {private String url;public AbstractResource() {}public AbstractResource(String url) {this.url url;}//子类都要实现的方法public abstract InputStream getInputStream();
}
public class FileResource extends AbstractResource {public FileResource() {super();}public FileResource(String url) {super(url);}Overridepublic InputStream getInputStream() {return null;}
}抽象工厂和具体工厂 public interface IResourceFactory {public AbstractResource create(String url);
}
public class FileResourceFactory implements IResourceFactory {Overridepublic AbstractResource create(String url) {//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......return new FileResource(url);}
}测试 Slf4j
public class ResourceLoaderMethod {private IResourceFactory resourceFactory;private static MapString, IResourceFactory resourceFactoryCache new HashMap(8);static {//在类加载的时候/起一个定时器,定时读取配置文件InputStream inputStream Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceFactory.properties);Properties properties null;try {properties new Properties();properties.load(inputStream);} catch (IOException e) {throw new RuntimeException(e);}SetMap.EntryObject, Object entries properties.entrySet();IteratorMap.EntryObject, Object iterator entries.iterator();while (iterator.hasNext()) {Map.EntryObject, Object next iterator.next();String prefixKey next.getKey().toString();String className next.getValue().toString();Class? clazz null;try {clazz Class.forName(className);IResourceFactory instance (IResourceFactory) clazz.getConstructor().newInstance();resourceFactoryCache.put(prefixKey, instance);} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException |InvocationTargetException e) {throw new RuntimeException(e);}}}private AbstractResource load(String url) {String prefix getPrefix(url);return resourceFactoryCache.get(prefix).create(url);}private String getPrefix(String url) {if (url null || .equals(url) || url.contains(:)) {return default;}String[] split url.split(:);return split[0];}public static void main(String[] args) {ResourceLoaderMethod rlm new ResourceLoaderMethod();AbstractResource load rlm.load(file:user/inter);System.out.println(load.getUrl() load.getUrl());}
}这段代码展示了使用抽象工厂设计模式的资源加载器实现。 抽象产品和具体产品部分 AbstractResource 是抽象产品类它包含了一个 url 字段并定义了一个抽象方法 getInputStream()。FileResource 是具体产品类它继承自 AbstractResource实现了抽象方法 getInputStream()。 抽象工厂和具体工厂部分 IResourceFactory 是抽象工厂接口它定义了一个方法 create()用于创建抽象产品 AbstractResource 对象。FileResourceFactory 是具体工厂类实现了 IResourceFactory 接口。在 create() 方法中它通过复杂的逻辑创建一个 FileResource 对象并将其返回。 测试部分 ResourceLoaderMethod 类中包含了一个静态的 resourceFactoryCache 缓存用于存储不同前缀对应的具体工厂对象。在静态代码块中通过读取配置文件 resourceFactory.properties获取了具体工厂类的映射关系并将其实例化放入缓存中。load() 方法根据传入的 URL 获取前缀并从 resourceFactoryCache 缓存中获取对应的具体工厂对象然后调用其 create() 方法创建抽象产品对象。getPrefix() 方法用于从 URL 中提取前缀如果 URL 为空、空字符串或包含冒号则返回默认前缀。在 main() 方法中创建 ResourceLoaderMethod 对象并通过调用 load() 方法加载资源。最后打印出加载的资源的 URL。
通过这段代码资源加载器实现了抽象工厂设计模式。客户端只需与抽象工厂接口 IResourceFactory 进行交互通过调用其 create() 方法由具体工厂类根据传入的 URL 创建相应的具体产品对象。这样可以实现客户端与具体产品类的解耦提高了代码的灵活性和可维护性。
3.总结
工厂方法模式Factory Method Design Pattern的优点 符合开闭原则工厂方法模式通过将对象的创建委托给子类实现了对扩展开放、对修改关闭。通过添加新的具体工厂子类可以轻松地新增产品类型而无需修改现有的代码。 提供了灵活性工厂方法模式将对象的创建委托给子类使得客户端可以通过选择不同的具体工厂子类来获取不同类型的对象实例。这提供了灵活性使得系统能够根据需求动态地创建所需的对象。 封装了对象的创建逻辑工厂方法模式将对象的创建逻辑封装在具体工厂子类中使得客户端代码与具体对象的创建过程解耦。客户端只需关心使用工厂方法获得对象无需关心对象的具体创建细节。 可以应对复杂的对象创建逻辑工厂方法模式适用于需要根据不同的条件或参数来创建对象的情况。每个具体工厂子类可以实现自己特定的对象创建逻辑使得系统能够处理复杂的对象创建需求。
工厂方法模式的缺点 类的数量增加引入工厂方法模式会增加系统中类的数量每个具体产品对应一个具体工厂类这可能会增加代码的复杂性和理解的难度。 客户端需要知道具体工厂类客户端需要知道具体工厂类才能创建相应的对象这增加了客户端代码的依赖性。如果客户端不知道具体工厂类需要进一步结合其他模式如抽象工厂模式来解决这个问题。
总结工厂方法模式提供了一种灵活的对象创建机制能够根据具体需求选择不同的具体工厂子类来创建对象。它符合开闭原则可以应对复杂的对象创建逻辑。然而它可能会增加系统中的类数量并要求客户端知道具体工厂类。根据具体情况可以考虑使用工厂方法模式来实现灵活、可扩展的对象创建。
四、抽象工厂
总结就是一个工厂生产一组产品线
1.简介
抽象工厂设计模式Abstract Factory Pattern是一种创建型设计模式用于创建一系列相关或相互依赖的对象。它提供了一个抽象工厂接口允许客户端使用抽象接口创建一组相关的产品对象而无需关心具体的产品类。
核心思想是将对象的创建委托给一个抽象工厂接口具体的工厂类实现这个接口并负责创建一族相关的产品。每个具体工厂类负责创建特定的产品这些产品在接口层面上有相关性。
抽象工厂模式通常包含以下角色 抽象工厂Abstract Factory定义创建一族产品的抽象接口。它通常包含多个用于创建不同产品的抽象方法。 具体工厂Concrete Factory实现抽象工厂接口负责创建一族具体产品对象。 抽象产品Abstract Product定义产品的共同接口或抽象类。具体产品类需要实现这个接口或继承这个抽象类。 具体产品Concrete Product实现抽象产品接口或继承抽象产品类是具体工厂所创建的对象实例。
抽象工厂模式通过引入抽象工厂和具体工厂来解决直接实例化具体产品的问题。客户端代码只需要与抽象工厂进行交互而不需要直接与具体产品类打交道。具体的产品对象由具体工厂类来创建具体工厂类的选择由客户端来决定。
2.案例 抽象产品和具体产品 public interface IResource {//子类都要实现的方法InputStream getInputStream();
}
Data
public abstract class AbstractVideoResource implements IResource {private String url;public AbstractVideoResource() {}public AbstractVideoResource(String url) {this.url url;}public void transformMp4() {System.out.println(视频资源组共有方法-transformMp4());}
}
Data
public abstract class AbstractTextResource implements IResource {private String url;public AbstractTextResource() {}public AbstractTextResource(String url) {this.url url;}public void transformUtf8() {System.out.println(文本资源组共有方法-transformUtf8());}
}
Data
public abstract class AbstractPictureResource implements IResource {private String url;public AbstractPictureResource() {}public AbstractPictureResource(String url) {this.url url;}public void transformJpg() {System.out.println(图片资源组共有方法-transformJpg());}
}public class FileTextResource extends AbstractTextResource {Overridepublic InputStream getInputStream() {return null;}
}
public class FileVideResource extends AbstractVideoResource {Overridepublic InputStream getInputStream() {return null;}
}
public class FilePictureResource extends AbstractPictureResource {public FilePictureResource() {super();}public FilePictureResource(String url) {super(url);}Overridepublic InputStream getInputStream() {return null;}
}
public class HttpPictureResource extends AbstractPictureResource {public HttpPictureResource() {super();}public HttpPictureResource(String url) {super(url);}Overridepublic InputStream getInputStream() {return null;}
}
public class HttpTextResource extends AbstractPictureResource {public HttpTextResource() {super();}public HttpTextResource(String url) {super(url);}Overridepublic InputStream getInputStream() {return null;}
}
public class HttpVideoResource extends AbstractPictureResource {public HttpVideoResource() {super();}public HttpVideoResource(String url) {super(url);}Overridepublic InputStream getInputStream() {return null;}
}抽象工厂和具体工厂 public interface IResourceFactory {public AbstractPictureResource create(String url);/*** 加载图片资源的工厂方法** param url 给的的资源url* return 图片资源*/public AbstractPictureResource loadPicture(String url);/*** 加载视频资源的工厂方法** param url 给的的资源url* return 视频资源*/public AbstractVideoResource loadVideo(String url);/*** 加载文本资源的工厂方法** param url 给的的资源url* return 文本资源*/public AbstractTextResource loadText(String url);
}public abstract class AbstractResourceFactory implements IResourceFactory {//可提供共享的模板方法、资源等
}public class FileResourceFactory extends AbstractResourceFactory {Overridepublic AbstractPictureResource create(String url) {//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......return new FilePictureResource(url);}Overridepublic AbstractPictureResource loadPicture(String url) {return null;}Overridepublic AbstractVideoResource loadVideo(String url) {return null;}Overridepublic AbstractTextResource loadText(String url) {return null;}
}
public class HttpResourceFactory extends AbstractResourceFactory {Overridepublic AbstractPictureResource create(String url) {//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......//很复杂的逻辑......return new HttpPictureResource(url);}Overridepublic AbstractPictureResource loadPicture(String url) {return null;}Overridepublic AbstractVideoResource loadVideo(String url) {return null;}Overridepublic AbstractTextResource loadText(String url) {return null;}
}测试 Slf4j
public class ResourceLoaderMethod {private IResourceFactory resourceFactory;private static MapString, IResourceFactory resourceFactoryCache new HashMap(8);static {//在类加载的时候/起一个定时器,定时读取配置文件InputStream inputStream Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceFactory.properties);Properties properties null;try {properties new Properties();properties.load(inputStream);} catch (IOException e) {throw new RuntimeException(e);}SetMap.EntryObject, Object entries properties.entrySet();IteratorMap.EntryObject, Object iterator entries.iterator();while (iterator.hasNext()) {Map.EntryObject, Object next iterator.next();String prefixKey next.getKey().toString();String className next.getValue().toString();Class? clazz null;try {clazz Class.forName(className);IResourceFactory instance (IResourceFactory) clazz.getConstructor().newInstance();resourceFactoryCache.put(prefixKey, instance);} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException |InvocationTargetException e) {throw new RuntimeException(e);}}}private AbstractPictureResource load(String url) {String prefix getPrefix(url);return resourceFactoryCache.get(prefix).create(url);}private String getPrefix(String url) {if (url null || .equals(url) || url.contains(:)) {return default;}String[] split url.split(:);return split[0];}public static void main(String[] args) {ResourceLoaderMethod rlm new ResourceLoaderMethod();AbstractPictureResource load rlm.load(file:user/inter);System.out.println(load.getUrl() load.getUrl());}
}这段代码展示了抽象工厂设计模式的实现。 抽象产品和具体产品部分 IResource 是抽象产品接口定义了一个 getInputStream() 方法。AbstractVideoResource、AbstractTextResource 和 AbstractPictureResource 是抽象产品的具体实现它们分别继承了 IResource 接口并包含了一些额外的共有方法。FileTextResource、FileVideoResource、FilePictureResource、HttpPictureResource、HttpTextResource 和 HttpVideoResource 是具体产品类分别继承了抽象产品的具体实现类并实现了 getInputStream() 方法。 抽象工厂和具体工厂部分 IResourceFactory 是抽象工厂接口它定义了创建产品的抽象方法以及加载具体产品的工厂方法。AbstractResourceFactory 是抽象工厂的具体实现它继承了 IResourceFactory 接口可以提供共享的模板方法和资源等。FileResourceFactory 和 HttpResourceFactory 是具体工厂类分别继承了抽象工厂的具体实现类实现了创建具体产品和加载具体产品的方法。 测试部分 ResourceLoaderMethod 类中的 resourceFactoryCache 是一个静态缓存用于存储不同前缀对应的具体工厂对象。在类加载时通过读取配置文件动态创建具体工厂对象并将其放入缓存中。load() 方法根据传入的 URL 获取前缀并从 resourceFactoryCache 缓存中获取对应的具体工厂对象。然后通过具体工厂对象调用 create() 方法创建抽象产品对象。getPrefix() 方法用于从 URL 中提取前缀如果 URL 为空、空字符串或包含冒号则返回默认前缀。
在 main() 方法中创建了 ResourceLoaderMethod 对象并通过调用 load() 方法加载资源。最后打印出加载的资源的 URL。
这段代码实现了抽象工厂设计模式通过抽象产品、具体产品、抽象工厂和具体工厂的定义将产品的创建过程从客户端代码中解耦出来。客户端只需要与抽象工厂进行交互而不需要直接依赖具体产品类。这提高了代码的灵活性、可扩展性和可维护性。
3.总结
抽象工厂模式Abstract Factory Design Pattern是一种创建型设计模式它提供一个接口或抽象类作为工厂允许客户端使用该接口或抽象类来创建一系列相关或依赖的对象。抽象工厂模式旨在提供一种创建对象族的方式而无需指定具体的类。
抽象工厂模式的优点 提供了一种统一的接口抽象工厂模式定义了一组相关对象的创建接口或抽象类使得客户端可以通过统一的接口来创建一系列相关的产品对象而无需关心具体的实现类。 实现了产品族的概念抽象工厂模式支持一次性创建一整个产品族。产品族是指由相互关联或依赖的一组相关对象组成的集合。通过抽象工厂模式可以一次性创建一整个产品族确保这些产品对象之间相互匹配、协同工作。 符合开闭原则抽象工厂模式使得新增产品族变得相对容易。通过添加新的具体工厂类和产品类可以扩展抽象工厂模式而无需修改现有的代码符合开闭原则。 封装了对象的创建细节抽象工厂模式将对象的创建过程封装在具体工厂类中使得客户端无需关心对象的具体创建细节从而提高了代码的封装性和可维护性。
抽象工厂模式的缺点 难以支持新种类的产品当需要添加新种类的产品时需要修改抽象工厂接口或抽象类以及所有的具体工厂类这可能对现有的代码和实现造成一定的影响。 增加了系统的复杂性引入抽象工厂模式会增加系统中的类和对象的数量这增加了系统的复杂性和理解的难度。
总结抽象工厂模式提供了一种创建一系列相关或依赖对象的方式通过一组接口或抽象类定义了对象的创建过程实现了产品族的概念。它提供了一种统一的接口封装了对象的创建细节并符合开闭原则。然而抽象工厂模式难以支持新种类的产品并增加了系统的复杂性。根据具体需求可以考虑使用抽象工厂模式来创建一系列相关的对象。