作业一: 请在草稿纸上手写一个单例模式的实现代码,拍照提交作业。
作业二:请用组合设计模式编写程序,打印输出图 1 的窗口,窗口组件的树结构如图 2 所示,打印输出示例参考图 3。
先上图:
父类:Component
public abstract class Component {
protected String name;
protected String type;
public Component(String name, String type) {
this.name = name;
this.type = type;
}
public abstract String getName();
public abstract String getType();
//Can use default throw new UnsupportedOperationException() and subclass override
public abstract void add(Component component);
public abstract void delete(Component component);
public abstract void printAll();
}
复制代码
容器组件(Frame):
public class Container extends Component {
private List<Component> components = new LinkedList<>();
public Container(String name, String type) {
super(name, type);
}
@Override
public String getName() {
return super.name;
}
@Override
public String getType() {
return super.type;
}
@Override
public void add(Component component) {
this.components.add(component);
}
@Override
public void delete(Component component) {
this.components.remove(component);
}
@Override
public void printAll() {
System.out.println("print " + getName() + "(" + getType() + ")");
this.components.forEach(c -> {
c.printAll();
//System.out.println("print " + c.getName() + "(" + c.getType() + ")");
});
}
}
复制代码
一般组件(Widget):
public class Widget extends Component {
public Widget(String name, String type) {
super(name, type);
}
@Override
public String getName() {
return super.name;
}
@Override
public String getType() {
return super.type;
}
@Override
public void add(Component component) {
throw new UnsupportedOperationException();
}
@Override
public void delete(Component component) {
throw new UnsupportedOperationException();
}
@Override
public void printAll() {
System.out.println("print " + getName() + "(" + getType() + ")");
}
}
复制代码
客户端(Client):
public class Client {
public static void main(String[] args) {
Container winFrom = new Container("WINDOW窗口", "WinForm");
Widget picture = new Widget("LOGO图片", "Picture");
Widget loginButton = new Widget("登录", "Button");
Widget registerButton = new Widget("注册", "Button");
Container frame = new Container("FRAME1", "Frame");
Widget userNameLabel = new Widget("用户名", "Label");
Widget userNameTextBox = new Widget("文本框", "TextBox");
Widget passwordLabel = new Widget("密码", "Label");
Widget passwordBox = new Widget("密码框", "PasswordBox");
Widget remindCheckBox = new Widget("复选框", "CheckBox");
Widget remindTextBox = new Widget("记住用户名", "TextBox");
Widget forgetPwLinkedLabel = new Widget("忘记密码", "LinkedLabel");
winFrom.add(picture);
winFrom.add(loginButton);
winFrom.add(registerButton);
winFrom.add(frame);
frame.add(userNameLabel);
frame.add(userNameTextBox);
frame.add(passwordLabel);
frame.add(passwordBox);
frame.add(remindCheckBox);
frame.add(remindTextBox);
frame.add(forgetPwLinkedLabel);
//winFrom.delete();
//frame.delete();
winFrom.printAll();
//UnsupportedOperationException
picture.add(loginButton);
}
}
复制代码
输出:
print WINDOW窗口(WinForm)
print LOGO图片(Picture)
print 登录(Button)
print 注册(Button)
print FRAME1(Frame)
print 用户名(Label)
print 文本框(TextBox)
print 密码(Label)
print 密码框(PasswordBox)
print 复选框(CheckBox)
print 记住用户名(TextBox)
print 忘记密码(LinkedLabel)
Exception in thread "main" java.lang.UnsupportedOperationException
at com.example.demo.geek.Widget.add(Widget.java:24)
at com.example.demo.geek.Client.main(Client.java:35)
Process finished with exit code 1
复制代码
这样虽然满足了要求,但是非 Container 类型的组件也具备了 add 和 delete 的方法,违反了接口隔离原则,尝试做些改变(最开始用多继承的方式,实现不好,后改成接口的方式):
所有组件都有 print 功能,所以基类直接实现 Printer 接口,容器组件另外单独实现 Frame 接口:
代码:
Printer 接口:
public interface Printer {
void printAll();
}
复制代码
Frame 接口:
public interface Frame {
void add(NewComponent component);
void delete(NewComponent component);
}
复制代码
NewComponent:
public abstract class NewComponent implements Printer {
private String name;
private String type;
public NewComponent(String name, String type) {
this.name = name;
this.type = type;
}
public String getName(){
return this.name;
};
public String getType(){
return this.type;
}
}
复制代码
NewContainer:
public class NewContainer extends NewComponent implements Frame {
private List<NewComponent> components = new LinkedList<>();
public NewContainer(String name, String type) {
super(name, type);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getType() {
return super.getType();
}
@Override
public void add(NewComponent component) {
this.components.add(component);
}
@Override
public void delete(NewComponent component) {
this.components.remove(component);
}
@Override
public void printAll() {
System.out.println("print " + getName() + "(" + getType() + ")");
this.components.forEach(c -> {
c.printAll();
});
}
}
复制代码
NewWidget:
public class NewWidget extends NewComponent {
public NewWidget(String name, String type) {
super(name, type);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getType() {
return super.getType();
}
@Override
public void printAll() {
System.out.println("print " + getName() + "(" + getType() + ")");
}
}
复制代码
NewClient:
public class NewClient {
public static void main(String[] args) {
NewContainer winFrom = new NewContainer("WINDOW窗口", "WinForm");
NewWidget picture = new NewWidget("LOGO图片", "Picture");
NewWidget loginButton = new NewWidget("登录", "Button");
NewWidget registerButton = new NewWidget("注册", "Button");
NewContainer frame = new NewContainer("FRAME1", "Frame");
NewWidget userNameLabel = new NewWidget("用户名", "Label");
NewWidget userNameTextBox = new NewWidget("文本框", "TextBox");
NewWidget passwordLabel = new NewWidget("密码", "Label");
NewWidget passwordBox = new NewWidget("密码框", "PasswordBox");
NewWidget remindCheckBox = new NewWidget("复选框", "CheckBox");
NewWidget remindTextBox = new NewWidget("记住用户名", "TextBox");
NewWidget forgetPwLinkedLabel = new NewWidget("忘记密码", "LinkedLabel");
winFrom.add(picture);
winFrom.add(loginButton);
winFrom.add(registerButton);
winFrom.add(frame);
frame.add(userNameLabel);
frame.add(userNameTextBox);
frame.add(passwordLabel);
frame.add(passwordBox);
frame.add(remindCheckBox);
frame.add(remindTextBox);
frame.add(forgetPwLinkedLabel);
//winFrom.delete();
//frame.delete();
winFrom.printAll();
}
}
复制代码
运行结果:
这样结果相同,但是 NewWidget 无法使用 add 和 delete 了,当然,之前调用也会报 UnsupportedOperationException!但是这种东西最好不要轻易暴露给不明白的使用者。
NewContainer:
NewWidget:
作业三:根据当周学习情况,完成一篇学习总结
设计模式的定义:
什么是设计模式?
每一种模式都描述了一种问题的通用解决方案。这种问题在我们的环境中,不停的出现。
设计模式是一种可重复使用的解决方案。
一个设计模式的组成部分:
模式名称:由少量的字组成的名称,有助于我们表达我们的设计。
待解问题:描述了何时需要运用这种模式,以及运用模式的环境。
解决方案:描述了组成设计的元素,他们的关系,职责和合作。但是这种描述是抽象的。
结论:运用这种解决方案所带来的的利与弊。主要是指该模式的弹性、扩展性、可移植性。
设计模式的分类:
从功能分类:
创建模式:对象实例化过程的抽象。
结构模式:将类或者对象结合在一起形成更大的构成。
行为模式:对不同的对象之间划分责任和算法的抽象化。
从方式分类:
类模式:以继承的方式实现模式,静态的。
对象模式:以组合的方式实现模式,动态的。
设计模式:
1.简单工厂:
简单工厂模式属于创建型模式又叫做静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
2.单例模式:
单例模式保证产生单一实例,就是说一个类只产生一个实例。使用单例模式有两个原因:
-可以减少实例频繁创建和销毁带来的资源损耗;
-当多个用户使用这个实例的时候,便于进行统一控制;
3.适配器模式:
系统需要使用现有的类,而这个类的接口与我们所需要的接口不同:
-例如:我们需要对 List 进行排序,但我们需要一个 Sortable 接口,原有的 List 接口不能满足要求。
一般适配器的应用:
-JDBCDriver:是对具体数据库的适配。
-JDBC-ODBC Bridge:将 Windows ODBC 适配到 JDBC 接口中。
4.模板方法模式:
模板方法模式是扩展功能的最基本模式之一: 它是一种“类的行为模式”。
它是通过“继承”的方式来实现扩展:基类负责算法的轮廓和骨架,子类负责算法的具体实现。、
5.组合模式:
组合模式是一种“对象的结构模式”,适合处理树形结构的数据。
组合模式使得用户可以使用一致的方法操作单个对象和组合对象。
6.装饰器模式
装饰器模式也被笼统地称为包装器,装饰器模式是一种“对象的结构模式”。
作用:在不改变对客户端的接口的前提下,扩展现有对象的功能。
设计模式不少,每种设计模式都是为了解决某一类问题,所以,灵活运用设计模式的前提是要想好需要应对的场景和情景,当然,会写代码,有设计模式思维也很重要,能融会贯通更重要!
评论