概述
软件体系结构设计模式
一【实验目的】
- 理解设计模式基本概念
- 掌握主要的设计模式
二【实验内容】
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("推文:今天是个好日子!"); //观察者做出反应
}
}
遇到的问题:在写工厂的三种模式时候,搞不清三种工厂模式的区别以及各自的优缺点,并且不熟悉三种方法的代码具体该怎么写。对抽象工厂模式比较陌生,对抽象工厂模式的分类以及分族不是很了解。
解决方法:不了解工厂方法的三种模式,就去网上分别看了三种方法的解释以及具体代码实现,并且熟练敲了很多遍,基本已经熟练掌握。
实验感想:在学了设计模式之后,我发现代码不能只是简单地实现功能了,而是代码要能够轻松地实现扩展功能,而不能改变其中已经定义好的内部逻辑。可以增加代码而要尽量避免修改代码。学习了设计模式之后虽然代码的复杂度变高了,但是对于代码以后的功能扩展确实铺了一条好路。
最后
以上就是专一金针菇为你收集整理的软件体系结构设计模式的全部内容,希望文章能够帮你解决软件体系结构设计模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复