设计模式-工厂模式-简单工厂

  最近在学习java 的设计模式,在网上看到了很多资料。全部总结在这里,希望大家互相学习。

Java 有 23 种设计模式,可分为三类:

1.创建模式

2.行为模式

3.结构模式 

在本文章中首先对创建模式进行介绍: 

 

n
创建模式分为类的创建模式对象的创建模式两种。
#对象的创建模式:是把对象的创建过程动态的委派给另一个对象,从而动态地决定客户端将得到哪些具体类的实例,以及这些类的实例是如何被创建和组合在一起的.
#类的创建模式:类的创建模式使用继承关系,把类的创建延迟到子类,从而封装了客户端将得到哪些具体类的信息,并且隐藏了这些类的实例是如何被创建和放在一起的。 创建模式(Creational Pattern)是对类的实例化过程的抽象化。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎样构造和封装这些动态的决定。
l
l
创建模式按常用功能可以分为四种:
1.简单工厂模式  (Simple Factory)
2.工厂方法模式  (Factory Method)
3.抽象工厂模式  (Abstract Factory)
4.单例模式模式  (Singleton)
第一:介绍简单工厂模式
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
#怎样实现简单工厂:
   简单工厂使用了java的 接口技术,那么我们怎样实现简单工厂呢:
    1,定义接口(Fruit)
    2,创建 实现接口 的类 (Grape,Strawberry,Apple)
    3,创建 工厂类(FruitGardener)
    4,在客户端 创建工厂对象,进而产生实例对象。
引入简单工厂模式
下面让我们来分析几个需求,然后我们使用简单工厂对其进行设计,看看能够给我的带来 什么样的好处。
需求1:有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列的水果:
l 葡萄 Grape
l 草莓 Strawberry
l 苹果 Apple
 首先我们认知到农场里可能还有不是水果类的植物,那么我们为了可以把它们和水果区分 开,我们就需要为水果提供一个共通的定义凡是具有这种定义的我们就似其为水果。
定义一个接口 Fruit
public interface Fruit
 }
对于水果来说其具有:种植,生长,收获的共通行为。
public interface Fruit{
   void grow();//生长
   void harvest();//收获
   void plant();//种植
}
 
整体的类设计结构如下图:
 
    让我们根据分析后的UML来分别编写我们的具体实现:
Apple 是水果的一种,因此它实现了水果接口所声明的所有方法。另外,由于苹果是多年生植 物,因此多出一个treeAge属性,描述苹果树的年龄。
public class Apple implements Fruit{
public void grow(){
    System.out.println("Apple is growing...");
}
public void harvest(){
    System.out.println("Apple has been harvested.");
}
 public void plant(){
    System.out.println("Apple has been planted.");
}
public int getTreeAge()
{
     return treeAge;
}
public void setTreeAge(int treeAge)
{
    this.treeAge = treeAge;
 }
private int treeAge;
}
 
同样,Grape类是水果类的一种,也实现了Fruit接口。但由于葡萄分有籽和无籽两种,因此,比通常的水果多出 一个seedless属性。
public class Grape implements Fruit{
public void grow(){
 System.out.println("Grape is growing...");
}
public void harvest(){
                      System.out.println("Grape has been harvested.");
}
public void plant(){
     System.out.println("Grape has been planted.");
}
public boolean getSeedless(){
 return seedless;
}
public void setSeedless(boolean seedless){
 this.seedless = seedless;
}
private boolean seedless;
}
 
Strawberry 类实现了Fruit接口,因此,也是水果类的子类型。
public class Strawberry implements Fruit{
    public void grow(){
    System.out.println("Strawberry is growing...");
    }
    public void harvest(){
    System.out.println("Strawberry has been harvested.");
    }
    public void plant(){
      System.out.println("Strawberry has been planted.");
    }
}
 
让我们再次的来分析一下我们的系统,水果是不可能自己种自己的,所以在我们的系统中还缺一个园丁,那么现 在就让我们考虑一下关于园丁类的设计把。
首先我们知道我们需要的是一个会种水果的园丁FruitGardener,其次我们要告诉园丁我们需要他种 植什么样的水果,也就是说园丁要被一种行为去驱动。
定义FruitGardener类
public class FruitGardener{}
前面分析过园丁是按照行为驱动的,而取得的结果是种植出我们想要的水果。所以添加方法
createFruit(String which)返回值是Fruit
public class FruitGardener{
    public static Fruit createFruit(String which) {}
}
而前面我们知道我们需要葡萄(Grape)、草莓(Strawberry)、苹果(Apple)那么我们就根据我们的需求 来添加方法的行为。
public static Fruit createFruit(String which){
 if (which.equalsIgnoreCase("apple")){
      return new Apple();
 }
 else if (which.equalsIgnoreCase("strawberry")){
      return new Strawberry();
 }
 else if (which.equalsIgnoreCase("grape")){
            return new Grape();
        }
}
客户端应用:
public class FruitManerger
{
      public static void main(String[] args)
      {
             Fruit fruit =  FruitGardener.createFruit("apple");
             fruit.plant();
      }
 
}
现在在让我们来完善我们的设计,因为是由FruitGardener根据我们的行为指令来决定种植何种水果,那么也就是说如果我们的指令对FruitGardener来说是不可能完成的那么他也应该告诉我们他无法种植,所以我们要 设计一个异常BadFruitException
public class BadFruitException extends Exception{
private static final long serialVersionUID = 4506528838794787503L;
public BadFruitException(String msg){
     super(msg);
}
}
然后我们更改createFruit
public static Fruit createFruit(String which) throws BadFruitException{
 if (which.equalsIgnoreCase("apple")){
      return new Apple();
 }
 else if (which.equalsIgnoreCase("strawberry")){
      return new Strawberry();
 }
 else if (which.equalsIgnoreCase("grape")){
            return new Grape();
 } else{
            throw new BadFruitException("Bad fruit request");
   }
}
 
回顾:我们的设计完成了,我们回头看看我们的代码,在想想关于简单工厂模式的定义
我们会发现createFruit就是一个简单工厂模式的应用。
我们可以通过下面的图形来表明一个简单工厂的一般性结构:
 
任何的事物都有其正反两面,那下面在让我们看看简单工厂的优点和缺点的对比。
l 优点
 使用简单工厂使得客户端和业务层有效的被隔离开,由工厂来根据客户端的请求来创建适合的业务对象,让后在返回给客户端。客户端不知道业务对象是如何被创建的而业务层也不知道客户端的存在,也就是说对于客户端来说业务对象是透明的,而对于业务层客户端同样也是透明的,这样就实现的客户端和业务层的解耦合。
l 缺点
 因为所有的业务对象的实例化逻辑都是由这个简单工厂实现,也就是说这个工厂类集中了所有的产品创建逻辑,形成了一个无所不知的全能类,也称之为 God Class,当业务对象层次很复杂 时这个工厂存在大量的判断逻辑,对系统的扩展和文档性带来了负面的影响。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计题目:农夫果园 一个农场,专门种植销售各类水果,在这个系统中需要描述下列水果: 葡萄:Grape 草莓:Strawberry 苹果:Apple 水果与其他的植物有很大的不同,水果最终是可以采摘食用的。那么一个自然的做法就是建立一个各种水果都适用的接口,以便与农场里的其他植物区分开。水果接口规定出所有的水果都必须实现的接口,包括任何水果必须具备的方法:种植plant(),生长grow(),收获harvest()。 Apple类是水果中的一种,因此它实现了水果接口所声明的所有方法。另外,由于苹果是多年生植物,因此多出一个treeAge性质,描述苹果树的树龄。 Grape类是水果类的一种,也实现Fruit接口中所声明的所有方法。但由于葡萄分为有籽和无籽的两种,因此比通常的水果多出一个seedless性质。 Strawberry类也是水果的一种,也实现了Fruit接口。 农场的园丁也是系统的一部分,自然要由一个合适的类来代表。这个类就是FruitGardener,它会根据农场老板的要求,使用factory()方法创建出不同的水果对象,比如苹果(Apple),葡萄(Grape)或草莓(Strawberry)的实例。而如果接到不合法的要求,会提示错误。 农场的市场调查员也是系统的一部分,也需要一个类代表,这个类是MarketInquirer,它通过inquire()调查今年市场上哪一种水果热销。 农场的老板也是系统的一部分,仍需要一个类来代表,这个类是FruitBoss,他会根据市场调查员的反馈信息,通知农场的园丁今年种植哪种水果。 要求:请你根据上述系统需求,用Java语言设计这个农场系统,发挥你的想象力吧!
简单工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在此模式中,我们使用一个工厂类来创建不同类型的对象,而不是在代码中直接实例化对象。 对于你提到的三角形和圆形的创建和擦除,我们可以使用简单工厂模式来实现。首先,我们需要定义一个形状接口,它包含画图和擦除方法。然后,我们可以创建两个实现这个接口的类,分别是三角形和圆形类。接下来,我们创建一个工厂类,它包含一个方法,该方法接受一个字符串参数,根据参数的不同返回三角形或圆形对象。 以下是一个简单的示例代码,用于演示如何使用简单工厂模式来创建和擦除三角形和圆形: ```java interface Shape { void draw(); void erase(); } class Triangle implements Shape { @Override public void draw() { System.out.println("Draw a triangle."); } @Override public void erase() { System.out.println("Erase a triangle."); } } class Circle implements Shape { @Override public void draw() { System.out.println("Draw a circle."); } @Override public void erase() { System.out.println("Erase a circle."); } } class ShapeFactory { public static Shape createShape(String type) { if (type.equals("triangle")) { return new Triangle(); } else if (type.equals("circle")) { return new Circle(); } else { throw new IllegalArgumentException("Invalid shape type."); } } } public class Main { public static void main(String[] args) { Shape triangle = ShapeFactory.createShape("triangle"); triangle.draw(); triangle.erase(); Shape circle = ShapeFactory.createShape("circle"); circle.draw(); circle.erase(); } } ``` 在上面的代码中,我们首先定义了一个Shape接口,并创建了Triangle和Circle类来实现它。接下来,我们创建了一个ShapeFactory工厂类,它包含一个createShape方法,该方法根据传入的参数返回不同的形状对象。最后,我们在主方法中使用ShapeFactory来创建和擦除三角形和圆形。 这是一个简单的示例,演示了如何使用简单工厂模式来创建和擦除不同类型的形状。在实际应用中,我们可以使用工厂模式来创建和管理更复杂的对象,可以提高代码的可维护性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值