软件体系结构设计模式

java 专栏收录该内容
16 篇文章 0 订阅

软件体系结构设计模式

一【实验目的】

  1. 理解设计模式基本概念
  2. 掌握主要的设计模式
    二【实验内容】
    1. 简单工厂模式
    1)理解案例1,然后完成2)部分的实验
    我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。
    FactoryPatternDemo,我们的演示类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。

步骤 1
创建一个接口:
Shape.java

public interface Shape { 
void draw();
 }

步骤 2
创建实现接口的实体类。
Rectangle.java

public class Rectangle implements Shape {
 @Override 
public void draw() { 
System.out.println("Inside Rectangle::draw() method."); 
	} 
}

Square.java

public class Square implements Shape {
 @Override 
public void draw() {
 System.out.println("Inside Square::draw() method."); 
} 
}

Circle.java

public class Circle implements Shape { 
@Override 
public void draw() { 
System.out.println("Inside Circle::draw() method."); 
} 
}

步骤 3
创建一个工厂,生成基于给定信息的实体类的对象。
ShapeFactory.java

public class ShapeFactory { 
//使用 getShape 方法获取形状类型的对象 
public Shape getShape(String shapeType){ 
if(shapeType == null){
 return null; 
} 
if(shapeType.equalsIgnoreCase("CIRCLE")){ 
return new Circle(); 
} 
else if(shapeType.equalsIgnoreCase("RECTANGLE")){ 
return new Rectangle(); 
} 
else if(shapeType.equalsIgnoreCase("SQUARE")){ 
return new Square(); 
} 
return null;
 } 
} 

步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
FactoryPatternDemo.java

public class FactoryPatternDemo { 
public static void main(String[] args) { 
ShapeFactory shapeFactory = new ShapeFactory(); 
//获取 Circle 的对象,并调用它的 draw 方法 
Shape shape1 = shapeFactory.getShape("CIRCLE"); 
//调用 Circle 的 draw 方法 shape1.draw(); //获取 Rectangle 的对象,并调用它的 draw 方法 
Shape shape2 = shapeFactory.getShape("RECTANGLE"); 
//调用 Rectangle 的 draw 方法 shape2.draw(); //获取 Square 的对象,并调用它的 draw 方法 Shape shape3 = shapeFactory.getShape("SQUARE"); 
//调用 Square 的 draw 方法 
shape3.draw()
 } 
}

步骤 5
执行程序,输出结果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

2、工厂方法

2)以案例1简单工厂模式为启发,利用工厂方法模式思想,编程实现 下面例子的工厂模式
工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。

步骤一:
创建一个接口

public interface Mouse {
    void sayHi();
}

步骤二:
创建实体类实现接口

public class HpMouse implements Mouse{
    @Override
    public void sayHi() {
        System.out.println("sayHi:惠普鼠标");
    }
}
public class DellMouse implements Mouse{
    @Override
    public void sayHi() {
        System.out.println("sayHi:戴尔鼠标"); }
}

步骤三:
创建鼠标工厂抽象类

步骤四:
创建实体类工厂继承抽象类并实现抽象方法

public class DellMouseFactory extends MouseFactory{
    @Override
    public Mouse creatMouse() {
        return new DellMouse();
    }
}
public class HpMouseFactory extends MouseFactory{
    @Override
    public Mouse creatMouse() {
        return new HpMouse();}
}
 

步骤五:
使用该工厂创建对应的实体对象

public class MouseFactoryDemo {
    public static void main(String[] args) {
        MouseFactory DellMouseFactory=new DellMouseFactory();
        Mouse dellMouse=DellMouseFactory.creatMouse();
        dellMouse.sayHi();
        MouseFactory HpMouseFactory=new HpMouseFactory();
        Mouse HpMouse=HpMouseFactory.creatMouse();
        HpMouse.sayHi();
    }
}

2.理解抽象工厂思想,然后用一个例子来体现抽象工厂模式,并编程实现
例子说明:
假如我们要创建红色圆形、红色三角形、蓝色圆形、蓝色三角形四个对象,如果我们用工厂方法模式的话,这样一来我们系统中会增多非常多的工厂类,那么通过抽象工厂方法就可以解决这个问题,抽象工厂方法就是将对象等级和族进行分类,比如所有正方形为一个等级,所有红色形状为一个族。
下面是实现抽象工厂方法代码:
步骤一:
定义公共抽象接口并定义不同形状的具体实现类

public interface Shape {
    public void draw();
}
 

将不同的形状声明为抽象类(等级划分)并实现公共的抽象接口(Shape)

public abstract class Circle implements Shape{
    @Override
    public abstract void draw();
}
public abstract class Rectangle implements Shape{
    @Override
    public abstract void draw();
}

实现各自的抽象类

public class RedCircle extends Circle{
    @Override
    public void draw() {
        System.out.println("创建红色圆形对象!");
    }
}
public class BlueCircle extends Circle{
    @Override
    public void draw() {
        System.out.println("创建蓝色圆形对象!");
    }
}

public class RedRectangle extends Rectangle{
    @Override
    public void draw() {
        System.out.println("创建红色长方形对象!");
    }
}

public class BlueRectangle extends Rectangle{
    @Override
    public void draw() {
        System.out.println("创建蓝色长方形对象!");
    }
}

步骤二:
定义抽象工厂接口,并根据族(颜色)实现抽象工厂接口

public interface ShapeFactory {
    Shape getCircle();
    Shape getRectangle();
}

public class RedShapeFactory implements ShapeFactory{
    @Override
    public Shape getCircle() {
        return new RedCircle();
    }
    @Override
    public Shape getRectangle() {
        return new RedRectangle();
    }
}

public class BlueShapeFactory implements ShapeFactory{
    @Override
    public Shape getCircle() {
        return new BlueCircle();
    }
    @Override
    public Shape getRectangle() {
        return new BlueRectangle();
    }
}

步骤四:
测试代码

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        ShapeFactory redShapeFactory=new RedShapeFactory();
        redShapeFactory.getCircle().draw(); //创建红色圆对象并执行方法
        redShapeFactory.getRectangle().draw();//创建红色长方形对象并执行方法
        ShapeFactory blueShapeFactory=new BlueShapeFactory();
        blueShapeFactory.getCircle().draw();//创建蓝色圆对象并执行方法
        blueShapeFactory.getRectangle().draw();//创建蓝色长方形对象并执行方法
    }
}

说明 简单工厂,工厂方法和抽象工厂 的特点
简单工厂:
优点:1、不需要关心类的创建细节。
2、减轻类之间的耦合依赖,具体类的实现只是依赖于工厂,而不依赖于其他类。
缺点:1、扩展复杂,当简单工厂需要生产出另外一种产品的时候,需要扩展工厂的内部创建逻辑,比较有可能引起大的故障。
2、由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻集中到了一个工厂类中。
工厂方法:
优点:创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。这样就实现了开闭原则。首先完全实现‘开-闭 原则’,实现了可扩展。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
抽象工厂模式:
抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。
优点:抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
缺点:产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

3. 观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们

理解观察者模式思想,然后用一个例子来体现观察者模式,并编程实现
例子说明:
微信公众号中订阅了公众号,当公众号所有者发送推文的时候,会通知所有订阅了该公众号的所有用户,这个情景可以用观察者模式实现。
代码如下:
1、首先创建抽象观察者抽象接口,并创建具体观察者实现接口

public interface Observer {
    void getInfo(String str);
}
public class User1 implements Observer{
    private String name;
    public User1(String name){
        this.name=name;
    }
    //定义订阅者1
    @Override
    public void getInfo(String text) {
        System.out.println(name+"收到推文:"+text);
    }
}

public class User2 implements Observer{
    private String name;
    public User2(String name){
        this.name=name;
    }
    //定义订阅者2
    @Override
    public void getInfo(String str) {
        System.out.println(name+"收到推文:"+str);
    }
}

2、创建被观察者抽象方法,并创建实体类继承抽象方法,定义添加观察者方法和移除观察者方法,定义通知观察者方法

import java.util.ArrayList;
import java.util.List;

public abstract class Subject {
    public List<Observer> users=new ArrayList<>();
    public void addUser(Observer user){
        users.add(user);
    }
    public void removeUser(Observer user){
        users.remove(user);
    }
    public abstract void notifyObserver(String str);
}

定义实体类继承抽象目标,并实现抽象方法,使得所有观察者接收到信息

public class Manager extends Subject{
    //管理员发送推文,各个订阅者接收到推文
    @Override
    public void notifyObserver(String str) {
        for(Observer user:users){
            user.getInfo(str);
        }
    }
}

测试代码

public class WeiXinObserverDemo {
    public static void main(String[] args) {
        Subject manager=new Manager(); //创建被观察者
        User1 user1=new User1("渣渣林"); //创建观察者1
        User2 user2=new User2("波波波"); //创建观察者2
        manager.addUser(user1); //添加观察者1
        manager.addUser(user2); //添加观察者2
        manager.notifyObserver("推文:今天是个好日子!"); //观察者做出反应
    }
}

遇到的问题:在写工厂的三种模式时候,搞不清三种工厂模式的区别以及各自的优缺点,并且不熟悉三种方法的代码具体该怎么写。对抽象工厂模式比较陌生,对抽象工厂模式的分类以及分族不是很了解。
解决方法:不了解工厂方法的三种模式,就去网上分别看了三种方法的解释以及具体代码实现,并且熟练敲了很多遍,基本已经熟练掌握。
实验感想:在学了设计模式之后,我发现代码不能只是简单地实现功能了,而是代码要能够轻松地实现扩展功能,而不能改变其中已经定义好的内部逻辑。可以增加代码而要尽量避免修改代码。学习了设计模式之后虽然代码的复杂度变高了,但是对于代码以后的功能扩展确实铺了一条好路。

  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值