dart programming
This commit is contained in:
parent
aca7795379
commit
9deeecf9ae
|
@ -19,3 +19,5 @@ doc/api/
|
|||
*.js_
|
||||
*.js.deps
|
||||
*.js.map
|
||||
|
||||
.DS_Store
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
///
|
||||
/// Hello Dart World
|
||||
///
|
||||
void main() {
|
||||
var lang = "Dart";
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 注释
|
||||
*/
|
||||
print("Hello $lang World"); // 单行注释
|
||||
|
||||
///
|
||||
/// 多行
|
||||
/// 注释
|
||||
///
|
||||
print("This is my first $lang application");
|
||||
|
||||
print(3 / 24);
|
||||
print(true);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
///
|
||||
/// build in data types
|
||||
/// - All data types in Dart are Objects.
|
||||
///
|
||||
main(List<String> args) {
|
||||
// Numbers
|
||||
var num1 = 100; // type 'int'
|
||||
int num2 = 200;
|
||||
double num3 = 30.0;
|
||||
// float num4; [Error] dart语言没有float关键字,使用double
|
||||
print(
|
||||
"Numbers: num1=$num1, num2=$num2, num3=$num3, num1+num2=${num1 + num2}");
|
||||
|
||||
//num1 = num3; [Error] A value of type 'double' can't be assigned to a variable of type 'int'
|
||||
num1 = num2; // 'var' 定义的变量首次赋值后类型就不可以改变了, num1为'int'类型
|
||||
|
||||
print('');
|
||||
|
||||
// Strings
|
||||
String name = "Dart";
|
||||
var company = "Google"; // type 'String'
|
||||
print("$company $name");
|
||||
|
||||
// 多行文本
|
||||
String lines = 'hello \n'
|
||||
'dart \n'
|
||||
'Strings';
|
||||
print(lines);
|
||||
|
||||
// 字符串可以用单引号,也可以用双引号
|
||||
var s1 = ' "Hello" ';
|
||||
var s2 = " 'Dart' ";
|
||||
var s3 = " \"Google\" ";
|
||||
print("$s1, $s2, $s3");
|
||||
|
||||
print('');
|
||||
|
||||
// bool
|
||||
bool isValid = true;
|
||||
var isAlive = false; // type 'bool'
|
||||
print("$isValid $isAlive");
|
||||
|
||||
print('');
|
||||
|
||||
// dynamic
|
||||
int number; // 未赋值的变量默认值为'null'
|
||||
print(number == null ? 'null' : 'not null');
|
||||
|
||||
number = 123;
|
||||
dynamic obj = number;
|
||||
print("obj is 'int', value is $obj");
|
||||
|
||||
obj = "Hello";
|
||||
print("obj is 'String', value is $obj");
|
||||
|
||||
print('');
|
||||
|
||||
// final
|
||||
final langName = 'Dart';
|
||||
//langName = 'Java'; [Error] a final variable, can only be set once.
|
||||
|
||||
// const
|
||||
const PI = 3.14;
|
||||
print('$langName, $PI');
|
||||
|
||||
print('');
|
||||
|
||||
var c1 = Circle(20.0);
|
||||
var c2 = Circle(30.0);
|
||||
print("c1: ${c1.radius}");
|
||||
print("c2: ${c2.radius}");
|
||||
print("PI: ${Circle.PI}");
|
||||
}
|
||||
|
||||
class Circle {
|
||||
//const PI = 3.14; [Error] Only static fields can be declared as const.
|
||||
|
||||
// 常量必须在定义时赋值
|
||||
static const PI = 3.14;
|
||||
// final 的变量可以在构造函数中赋值
|
||||
final double radius;
|
||||
|
||||
Circle(this.radius);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
///
|
||||
/// conditional expressions
|
||||
///
|
||||
main(List<String> args) {
|
||||
// if-else
|
||||
var marks = 70;
|
||||
if (marks >= 90 && marks < 100) {
|
||||
print("A+ grade");
|
||||
} else if (marks >= 80 && marks < 90) {
|
||||
print("A grade");
|
||||
} else if (marks >= 70 && marks < 80) {
|
||||
print("B grade");
|
||||
} else if (marks >= 60 && marks < 70) {
|
||||
print("C grade");
|
||||
} else if (marks > 30 && marks < 60) {
|
||||
print("D grade");
|
||||
} else if (marks >= 0 && marks < 30) {
|
||||
print("You have failed");
|
||||
} else {
|
||||
print("Invalid Marks. Please try again !");
|
||||
}
|
||||
|
||||
// condition ? exp1 : exp2
|
||||
int a = 2;
|
||||
int b = 3;
|
||||
int smallNumber = a < b ? a : b;
|
||||
print("$smallNumber is smaller");
|
||||
|
||||
// exp1 ?? exp2
|
||||
String name;
|
||||
print(name ?? "Guest User");
|
||||
|
||||
// Switch Case Statements: Applicable for only 'int' and 'String'
|
||||
String grade = 'A';
|
||||
switch (grade) {
|
||||
case 'A':
|
||||
print("Excellent grade of A");
|
||||
break;
|
||||
case 'B':
|
||||
print("Very Good !");
|
||||
break;
|
||||
case 'C':
|
||||
print("Good enough. But work hard");
|
||||
break;
|
||||
case 'F':
|
||||
print("You have failed");
|
||||
break;
|
||||
default:
|
||||
print("Invalid Grade");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
///
|
||||
/// loop
|
||||
///
|
||||
main(List<String> args) {
|
||||
// for loop
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
print(i);
|
||||
}
|
||||
}
|
||||
|
||||
print('');
|
||||
|
||||
// for ..in loop
|
||||
List planetList = ["Mercury", "Venus", "Earth", "Mars"];
|
||||
for (String planet in planetList) {
|
||||
print(planet);
|
||||
}
|
||||
|
||||
print('');
|
||||
|
||||
// while loop
|
||||
var i = 1;
|
||||
while (i <= 10) {
|
||||
if (i % 2 == 0) {
|
||||
print(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
print('');
|
||||
|
||||
// do ..while loop
|
||||
do {
|
||||
i--;
|
||||
if (i < 5) {
|
||||
print(i);
|
||||
}
|
||||
} while (i > 0);
|
||||
|
||||
print('');
|
||||
|
||||
// break labels
|
||||
breakLabel: for (int x = 1; x < 100; x++) {
|
||||
for (int y = 1; y < 10; y++) {
|
||||
print("x=$x, y=$y");
|
||||
if (x == 1 && y == 3) {
|
||||
break breakLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print('');
|
||||
|
||||
// continue labels
|
||||
continueLabel: for (var m = 1; m < 3; m++) {
|
||||
for (var n = 0; n < 10; n++) {
|
||||
print("m=$m, n=$n");
|
||||
if (n==2) {
|
||||
continue continueLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
///
|
||||
/// functions
|
||||
///
|
||||
main(List<String> args) {
|
||||
var n = add(200, 100);
|
||||
print(n);
|
||||
|
||||
var m = minus(200, 100);
|
||||
print(m);
|
||||
|
||||
output('Hello');
|
||||
|
||||
func(1, 2, 3);
|
||||
func(4, 5);
|
||||
func(6);
|
||||
|
||||
print('');
|
||||
|
||||
func2(10, a: 1, b: 2);
|
||||
func2(0, b: 3);
|
||||
|
||||
print('');
|
||||
|
||||
fun3(1);
|
||||
fun3(1, y: 2);
|
||||
}
|
||||
|
||||
int add(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
// 函数返回值类型为dynamic
|
||||
minus(int x, int y) {
|
||||
return x - y;
|
||||
}
|
||||
|
||||
// '=>' 等价于 '{return xxxx;}'
|
||||
output(var s) => print(s);
|
||||
|
||||
// Optional Parameters
|
||||
func(int a, [int b, int c]) {
|
||||
print("a is $a");
|
||||
print("b is $b");
|
||||
print("c is $c");
|
||||
}
|
||||
|
||||
// Optional Named Parameters
|
||||
func2(int x, {int a, int b}) {
|
||||
print("x is $x");
|
||||
print("a is $a");
|
||||
print("b is $b");
|
||||
}
|
||||
|
||||
// Optional Default Parameters
|
||||
fun3(int x, {int y = 10}) {
|
||||
print("x is $x");
|
||||
print("y is $y");
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
///
|
||||
/// exception handling
|
||||
///
|
||||
main(List<String> args) {
|
||||
// try ..on, 一般用于处理已知错误
|
||||
try {
|
||||
int result = 12 ~/ 0;
|
||||
print("The result is $result");
|
||||
} on IntegerDivisionByZeroException {
|
||||
print('Cannot divide by Zero');
|
||||
}
|
||||
|
||||
// try ..catch, 一般用于捕获未知错误
|
||||
try {
|
||||
int result = 12 ~/ 0;
|
||||
print("The result is $result");
|
||||
} catch (e) {
|
||||
print("The exception thrown is $e");
|
||||
}
|
||||
|
||||
// STACK TRAC
|
||||
try {
|
||||
int result = 12 ~/ 0;
|
||||
print("The result is $result");
|
||||
} catch (e, s) {
|
||||
print("The exception thrown is $e");
|
||||
print("STACK TRACE \n $s");
|
||||
}
|
||||
|
||||
// finally
|
||||
try {
|
||||
int result = 12 ~/ 0;
|
||||
print("The result is $result");
|
||||
} catch (e) {
|
||||
print("The exception thrown is $e");
|
||||
} finally {
|
||||
print("This is FINALLY Clause and is always executed.");
|
||||
}
|
||||
|
||||
// try ..finally
|
||||
try {
|
||||
int result = 12 ~/ 1;
|
||||
print("The result is $result");
|
||||
} finally {
|
||||
print("This is FINALLY Clause and is always executed.");
|
||||
}
|
||||
|
||||
// Custom Exception
|
||||
try {
|
||||
throwFunc();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomException implements Exception {
|
||||
@override
|
||||
String toString() {
|
||||
return "This is Custom Exception.";
|
||||
}
|
||||
}
|
||||
|
||||
throwFunc() {
|
||||
throw CustomException();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
///
|
||||
/// class and objects
|
||||
///
|
||||
main(List<String> args) {
|
||||
var student = Student(1);
|
||||
student.name = "Peter";
|
||||
student.study();
|
||||
|
||||
var tom = Student(2, name: 'Tom');
|
||||
tom.study();
|
||||
|
||||
var robot = Student.myCustomConstructor();
|
||||
robot.study();
|
||||
|
||||
}
|
||||
|
||||
class Student {
|
||||
// 下划线开头的表示私有(private)
|
||||
int _id = -1;
|
||||
String name;
|
||||
|
||||
// 构造函数赋值
|
||||
Student(this._id, {this.name});
|
||||
|
||||
// 自定义构造函数
|
||||
Student.myCustomConstructor() {
|
||||
_id = 0;
|
||||
name = 'Robot';
|
||||
}
|
||||
|
||||
// 属性(读)
|
||||
int get id => _id;
|
||||
|
||||
void study() {
|
||||
print("${this.name}(No.$_id) is now studying");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
///
|
||||
/// inheritance.dart
|
||||
///
|
||||
main(List<String> args) {
|
||||
Animal animal = Dog('black');
|
||||
animal.eat();
|
||||
(animal as Dog).bark();
|
||||
|
||||
if (animal is Duck) {
|
||||
print('Yes');
|
||||
} else {
|
||||
print('No');
|
||||
}
|
||||
|
||||
Duck duck = Duck('white');
|
||||
duck.eat();
|
||||
print(duck is Animal);
|
||||
|
||||
YellowFlyDuck yellowFlyDuck = YellowFlyDuck();
|
||||
yellowFlyDuck.eat();
|
||||
yellowFlyDuck.flyInSky();
|
||||
yellowFlyDuck.count();
|
||||
yellowFlyDuck.output();
|
||||
|
||||
print(Duck.type);
|
||||
// print(YellowFlyDuck.type);
|
||||
}
|
||||
|
||||
class Animal {
|
||||
String color;
|
||||
eat() {
|
||||
print('Eat!');
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Animal {
|
||||
Dog(String color) {
|
||||
super.color = color;
|
||||
}
|
||||
|
||||
@override
|
||||
eat() {
|
||||
print('$color dog eats meat.');
|
||||
}
|
||||
|
||||
void bark() {
|
||||
print("Bark !");
|
||||
}
|
||||
}
|
||||
|
||||
class Duck extends Animal {
|
||||
static String type = "DUCK";
|
||||
|
||||
Duck(String color) {
|
||||
super.color = color;
|
||||
}
|
||||
|
||||
@override
|
||||
eat() {
|
||||
print('$color duck eats rice.');
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Fly {
|
||||
void flyInSky();
|
||||
}
|
||||
|
||||
class CountableMixin {
|
||||
int _count = 0;
|
||||
|
||||
void count() {
|
||||
_count++;
|
||||
}
|
||||
|
||||
output() {
|
||||
print('count: $_count');
|
||||
}
|
||||
}
|
||||
|
||||
class YellowFlyDuck extends Duck with CountableMixin implements Fly {
|
||||
YellowFlyDuck() : super('Yellow');
|
||||
|
||||
@override
|
||||
void flyInSky() {
|
||||
print('$color duck Fly!');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
///
|
||||
/// lambda nameless function
|
||||
///
|
||||
main(List<String> args) {
|
||||
// Defining Lambda
|
||||
Function addFunc = (int a, int b) {
|
||||
var sum = a + b;
|
||||
print(sum);
|
||||
};
|
||||
|
||||
var addFunc2 = (int a, int b) => a + b;
|
||||
|
||||
addFunc(2, 3);
|
||||
print(addFunc2(3, 4));
|
||||
|
||||
var func = addFunc3;
|
||||
func(1, 2);
|
||||
|
||||
var newFunc = makeAddFunc();
|
||||
newFunc(2, 1);
|
||||
|
||||
printAddResult(addFunc2, 5, 5);
|
||||
}
|
||||
|
||||
// 普通函数
|
||||
addFunc3(int x, int y) {
|
||||
var sum = x + y;
|
||||
print(sum);
|
||||
}
|
||||
|
||||
// 返回一个'Function'
|
||||
Function makeAddFunc() {
|
||||
return (int x, int y) {
|
||||
var sum = x + y;
|
||||
print(sum);
|
||||
};
|
||||
}
|
||||
|
||||
// 接收一个'Function'类型的参数
|
||||
printAddResult(Function addFunc, int x, int y) {
|
||||
var sum = addFunc(x, y);
|
||||
print(sum);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
///
|
||||
/// Closures
|
||||
///
|
||||
main(List<String> args) {
|
||||
// A closure is a function that has access to the parent scope
|
||||
String message = "Dart is good";
|
||||
Function showMessage = () {
|
||||
message = "Dart is awesome";
|
||||
print(message);
|
||||
};
|
||||
showMessage();
|
||||
print(message);
|
||||
|
||||
// A closure is a function object that has access to variables in its lexical scope
|
||||
Function talk = () {
|
||||
String msg = "Hi";
|
||||
|
||||
Function say = () {
|
||||
msg = "Hello";
|
||||
print(msg);
|
||||
};
|
||||
|
||||
return say;
|
||||
};
|
||||
|
||||
Function speak = talk();
|
||||
speak();
|
||||
|
||||
talk()();
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
///
|
||||
/// Collections
|
||||
///
|
||||
main(List<String> args) {
|
||||
// Fixed-length list
|
||||
List<int> fixedNumList = List(5);
|
||||
fixedNumList[0] = 10;
|
||||
fixedNumList[1] = 11;
|
||||
fixedNumList[2] = 12;
|
||||
fixedNumList[3] = 13;
|
||||
fixedNumList[4] = 14;
|
||||
print(fixedNumList);
|
||||
|
||||
fixedNumList[0] = 100;
|
||||
fixedNumList[1] = null;
|
||||
print(fixedNumList);
|
||||
|
||||
for (var item in fixedNumList) {
|
||||
print(item);
|
||||
}
|
||||
|
||||
fixedNumList.forEach((element) => print(element ?? 'null value'));
|
||||
|
||||
print('length: ${fixedNumList.length}');
|
||||
|
||||
print('');
|
||||
|
||||
// Growable list
|
||||
List<String> growableList = ['aaa', 'bbb', 'ccc'];
|
||||
growableList.add('ddd');
|
||||
growableList.add('eee');
|
||||
growableList.addAll(['fff', 'ggg']);
|
||||
print(growableList);
|
||||
|
||||
growableList.remove('ggg');
|
||||
growableList.removeAt(2);
|
||||
print(growableList);
|
||||
|
||||
growableList.clear();
|
||||
print(growableList);
|
||||
|
||||
growableList..add('111')..add('222')..add('333');
|
||||
print(growableList);
|
||||
|
||||
// Map
|
||||
Map<String, int> fruits = {"apple": 1, "banana": 2, "guava": 3};
|
||||
fruits["pear"]=4;
|
||||
print(fruits);
|
||||
fruits.forEach((k, v) => print('key:$k,value:$v'));
|
||||
|
||||
// Set
|
||||
Set<String> countries = Set.from(["USA", "INDIA", "CHINA"]); // from a list
|
||||
countries.add("Japan");
|
||||
print(countries);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
///
|
||||
/// callable classes
|
||||
///
|
||||
main(List<String> args) {
|
||||
var call = Callable();
|
||||
call('Dart');
|
||||
}
|
||||
|
||||
class Callable {
|
||||
call(String name) => print('call $name');
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
工厂模式(Factory Pattern)
|
||||
|
||||
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
|
||||
主要解决:主要解决接口选择的问题。
|
||||
何时使用:我们明确地计划不同条件下创建不同实例时。
|
||||
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
var shapeFactory = 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();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Shape {
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Rectangle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Rectangle::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Square implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Square::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Circle::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个工厂
|
||||
///
|
||||
class ShapeFactory {
|
||||
//使用 getShape 方法获取形状类型的对象
|
||||
Shape getShape(String shapeType) {
|
||||
switch (shapeType?.toUpperCase()) {
|
||||
case "CIRCLE":
|
||||
return Circle();
|
||||
break;
|
||||
case "RECTANGLE":
|
||||
return Rectangle();
|
||||
break;
|
||||
case "SQUARE":
|
||||
return Square();
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
抽象工厂模式 (Abstract Factory Pattern)
|
||||
|
||||
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
|
||||
主要解决:主要解决接口选择的问题。
|
||||
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
|
||||
如何解决:在一个产品族里面,定义多个产品。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
//获取形状工厂
|
||||
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
|
||||
|
||||
//获取形状为 Circle 的对象
|
||||
Shape shape1 = shapeFactory.getShape("CIRCLE");
|
||||
shape1.draw();
|
||||
//获取形状为 Rectangle 的对象
|
||||
Shape shape2 = shapeFactory.getShape("RECTANGLE");
|
||||
shape2.draw();
|
||||
//获取形状为 Square 的对象
|
||||
Shape shape3 = shapeFactory.getShape("SQUARE");
|
||||
shape3.draw();
|
||||
|
||||
//获取颜色工厂
|
||||
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
|
||||
|
||||
//获取颜色为 Red 的对象
|
||||
Color color1 = colorFactory.getColor("RED");
|
||||
color1.fill();
|
||||
|
||||
//获取颜色为 Green 的对象
|
||||
Color color2 = colorFactory.getColor("GREEN");
|
||||
color2.fill();
|
||||
|
||||
//获取颜色为 Blue 的对象
|
||||
Color color3 = colorFactory.getColor("BLUE");
|
||||
color3.fill();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Shape {
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Rectangle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Rectangle::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Square implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Square::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Inside Circle::draw() method.");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 为颜色创建一个接口
|
||||
///
|
||||
abstract class Color {
|
||||
void fill();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Red implements Color {
|
||||
@override
|
||||
void fill() {
|
||||
print("Inside Red::fill() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Green implements Color {
|
||||
@override
|
||||
void fill() {
|
||||
print("Inside Green::fill() method.");
|
||||
}
|
||||
}
|
||||
|
||||
class Blue implements Color {
|
||||
@override
|
||||
void fill() {
|
||||
print("Inside Blue::fill() method.");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 为 Color 和 Shape 对象创建抽象类来获取工厂
|
||||
///
|
||||
abstract class AbstractFactory {
|
||||
Color getColor(String color);
|
||||
Shape getShape(String shape);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象
|
||||
///
|
||||
class ShapeFactory extends AbstractFactory {
|
||||
@override
|
||||
Shape getShape(String shapeType) {
|
||||
switch (shapeType?.toUpperCase()) {
|
||||
case "CIRCLE":
|
||||
return Circle();
|
||||
break;
|
||||
case "RECTANGLE":
|
||||
return Rectangle();
|
||||
break;
|
||||
case "SQUARE":
|
||||
return Square();
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Color getColor(String color) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ColorFactory extends AbstractFactory {
|
||||
@override
|
||||
Shape getShape(String shapeType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Color getColor(String color) {
|
||||
switch (color?.toUpperCase()) {
|
||||
case "RED":
|
||||
return Red();
|
||||
break;
|
||||
case "GREEN":
|
||||
return Green();
|
||||
break;
|
||||
case "BLUE":
|
||||
return Blue();
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂
|
||||
///
|
||||
class FactoryProducer {
|
||||
static AbstractFactory getFactory(String choice) {
|
||||
if (choice == "SHAPE") {
|
||||
return ShapeFactory();
|
||||
} else if (choice == "COLOR") {
|
||||
return ColorFactory();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
单例模式(Singleton Pattern)
|
||||
|
||||
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
|
||||
主要解决:一个全局使用的类频繁地创建与销毁。
|
||||
何时使用:当您想控制实例数目,节省系统资源的时候。
|
||||
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
var s1 = Singleton();
|
||||
var s2 = Singleton();
|
||||
print(identical(s1, s2));
|
||||
print(s1 == s2);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 实现单例模式
|
||||
///
|
||||
class Singleton {
|
||||
// 单例
|
||||
static final Singleton _instance = Singleton._();
|
||||
|
||||
// 私有构造器
|
||||
Singleton._();
|
||||
|
||||
// 工厂方法
|
||||
factory Singleton() {
|
||||
return _instance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
建造者模式(Builder Pattern)
|
||||
|
||||
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
|
||||
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
|
||||
何时使用:一些基本部件不会变,而其组合经常变化的时候。
|
||||
如何解决:将变与不变分离开。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
MealBuilder mealBuilder = new MealBuilder();
|
||||
|
||||
Meal vegMeal = mealBuilder.prepareVegMeal();
|
||||
print("Veg Meal");
|
||||
vegMeal.showItems();
|
||||
print("Total Cost: ${vegMeal.getCost()}");
|
||||
|
||||
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
|
||||
print("\n\nNon-Veg Meal");
|
||||
nonVegMeal.showItems();
|
||||
print("Total Cost: ${nonVegMeal.getCost()}");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个表示 食物条目 的接口
|
||||
///
|
||||
abstract class Item {
|
||||
String name();
|
||||
Packing packing();
|
||||
double price();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个表示 食物包装 的接口
|
||||
///
|
||||
abstract class Packing {
|
||||
String pack();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现 Packing 接口的实体类
|
||||
///
|
||||
class Wrapper implements Packing {
|
||||
@override
|
||||
String pack() {
|
||||
return "Wrapper";
|
||||
}
|
||||
}
|
||||
|
||||
class Bottle implements Packing {
|
||||
@override
|
||||
String pack() {
|
||||
return "Bottle";
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现 Item 接口的抽象类,该类提供了默认的功能
|
||||
///
|
||||
abstract class Burger implements Item {
|
||||
@override
|
||||
Packing packing() {
|
||||
return new Wrapper();
|
||||
}
|
||||
|
||||
@override
|
||||
double price();
|
||||
}
|
||||
|
||||
abstract class ColdDrink implements Item {
|
||||
@override
|
||||
Packing packing() {
|
||||
return new Bottle();
|
||||
}
|
||||
|
||||
@override
|
||||
double price();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了 Burger 和 ColdDrink 的实体类
|
||||
///
|
||||
class VegBurger extends Burger {
|
||||
@override
|
||||
double price() {
|
||||
return 25.0;
|
||||
}
|
||||
|
||||
@override
|
||||
String name() {
|
||||
return "Veg Burger";
|
||||
}
|
||||
}
|
||||
|
||||
class ChickenBurger extends Burger {
|
||||
@override
|
||||
double price() {
|
||||
return 50.5;
|
||||
}
|
||||
|
||||
@override
|
||||
String name() {
|
||||
return "Chicken Burger";
|
||||
}
|
||||
}
|
||||
|
||||
class Coke extends ColdDrink {
|
||||
@override
|
||||
double price() {
|
||||
return 30.0;
|
||||
}
|
||||
|
||||
@override
|
||||
String name() {
|
||||
return "Coke";
|
||||
}
|
||||
}
|
||||
|
||||
class Pepsi extends ColdDrink {
|
||||
@override
|
||||
double price() {
|
||||
return 35.0;
|
||||
}
|
||||
|
||||
@override
|
||||
String name() {
|
||||
return "Pepsi";
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个 Meal 类,带有上面定义的 Item 对象
|
||||
///
|
||||
class Meal {
|
||||
List<Item> _items = List<Item>();
|
||||
|
||||
void addItem(Item item) {
|
||||
_items.add(item);
|
||||
}
|
||||
|
||||
double getCost() {
|
||||
double cost = 0.0;
|
||||
for (Item item in _items) {
|
||||
cost += item.price();
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
void showItems() {
|
||||
for (Item item in _items) {
|
||||
print("Item : ${item.name()}");
|
||||
print(", Packing : ${item.packing().pack()}");
|
||||
print(", Price : ${item.price()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象
|
||||
///
|
||||
class MealBuilder {
|
||||
Meal prepareVegMeal() {
|
||||
Meal meal = new Meal();
|
||||
meal.addItem(new VegBurger());
|
||||
meal.addItem(new Coke());
|
||||
return meal;
|
||||
}
|
||||
|
||||
Meal prepareNonVegMeal() {
|
||||
Meal meal = new Meal();
|
||||
meal.addItem(new ChickenBurger());
|
||||
meal.addItem(new Pepsi());
|
||||
return meal;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
原型模式(Prototype Pattern)
|
||||
|
||||
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
|
||||
主要解决:在运行期建立和删除原型。
|
||||
何时使用:
|
||||
1、当一个系统应该独立于它的产品创建,构成和表示时。
|
||||
2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。
|
||||
3、为了避免创建一个与产品类层次平行的工厂类层次时。
|
||||
4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
|
||||
如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Prototype p1 = ConcretePrototype('Tom');
|
||||
Prototype p2 = p1.clone();
|
||||
|
||||
(p1 as ConcretePrototype)?.sayHello();
|
||||
(p2 as ConcretePrototype)?.sayHello();
|
||||
|
||||
print(p1);
|
||||
print(p2);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 定义一个原型接口
|
||||
///
|
||||
abstract class Prototype {
|
||||
Prototype clone();
|
||||
}
|
||||
|
||||
///
|
||||
/// 实现原型接口
|
||||
///
|
||||
class ConcretePrototype implements Prototype {
|
||||
String _name;
|
||||
|
||||
ConcretePrototype(this._name);
|
||||
|
||||
sayHello() {
|
||||
print('Hello $_name');
|
||||
}
|
||||
|
||||
@override
|
||||
Prototype clone() {
|
||||
return ConcretePrototype(_name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
适配器模式(Adapter Pattern)
|
||||
|
||||
意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
|
||||
主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
|
||||
何时使用:
|
||||
1、系统需要使用现有的类,而此类的接口不符合系统的需要。
|
||||
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。
|
||||
3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)
|
||||
|
||||
如何解决:继承、依赖(推荐)。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
AudioPlayer audioPlayer = new AudioPlayer();
|
||||
try {
|
||||
audioPlayer.play("mp3", "beyond the horizon.mp3");
|
||||
audioPlayer.play("mp4", "alone.mp4");
|
||||
audioPlayer.play("vlc", "far far away.vlc");
|
||||
audioPlayer.play("avi", "mind me.avi");
|
||||
} catch (e) {
|
||||
if (e is UnimplementedError) {
|
||||
print(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 为媒体播放器和更高级的媒体播放器创建接口
|
||||
///
|
||||
abstract class MediaPlayer {
|
||||
void play(String audioType, String fileName);
|
||||
}
|
||||
|
||||
abstract class AdvancedMediaPlayer {
|
||||
void playVlc(String fileName);
|
||||
void playMp4(String fileName);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 AdvancedMediaPlayer 接口的实体类
|
||||
///
|
||||
class VlcPlayer implements AdvancedMediaPlayer {
|
||||
@override
|
||||
void playVlc(String fileName) {
|
||||
print("Playing vlc file. Name: $fileName");
|
||||
}
|
||||
|
||||
@override
|
||||
void playMp4(String fileName) {
|
||||
throw UnimplementedError('当前播放器不能播放mp4.');
|
||||
}
|
||||
}
|
||||
|
||||
class Mp4Player implements AdvancedMediaPlayer {
|
||||
@override
|
||||
void playVlc(String fileName) {
|
||||
throw UnimplementedError('当前播放器不能播放vlc.');
|
||||
}
|
||||
|
||||
@override
|
||||
void playMp4(String fileName) {
|
||||
print("Playing mp4 file. Name: $fileName");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 MediaPlayer 接口的适配器类
|
||||
///
|
||||
class MediaAdapter implements MediaPlayer {
|
||||
AdvancedMediaPlayer advancedMusicPlayer;
|
||||
|
||||
MediaAdapter(String audioType) {
|
||||
if (audioType.toUpperCase() == "VLC") {
|
||||
advancedMusicPlayer = new VlcPlayer();
|
||||
} else if (audioType.toUpperCase() == "MP4") {
|
||||
advancedMusicPlayer = new Mp4Player();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void play(String audioType, String fileName) {
|
||||
if (audioType.toUpperCase() == "VLC") {
|
||||
advancedMusicPlayer.playVlc(fileName);
|
||||
} else if (audioType.toUpperCase() == "MP4") {
|
||||
advancedMusicPlayer.playMp4(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 MediaPlayer 接口的实体类
|
||||
///
|
||||
class AudioPlayer implements MediaPlayer {
|
||||
MediaAdapter mediaAdapter;
|
||||
|
||||
@override
|
||||
void play(String audioType, String fileName) {
|
||||
var _type = audioType?.toUpperCase();
|
||||
|
||||
//播放 mp3 音乐文件的内置支持
|
||||
if (_type == "MP3") {
|
||||
print("Playing mp3 file. Name: $fileName");
|
||||
}
|
||||
//mediaAdapter 提供了播放其他文件格式的支持
|
||||
else if (_type == "VLC" || _type == "MP4") {
|
||||
mediaAdapter = new MediaAdapter(audioType);
|
||||
mediaAdapter.play(audioType, fileName);
|
||||
} else {
|
||||
throw UnimplementedError(
|
||||
"Invalid media. $audioType format not supported");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
桥接(Bridge)
|
||||
|
||||
意图:将抽象部分与实现部分分离,使它们都可以独立的变化。
|
||||
主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
|
||||
何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。
|
||||
如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Shape redCircle = new Circle(100, 100, 10, new RedCircle());
|
||||
Shape greenCircle = new Circle(100, 100, 10, new GreenCircle());
|
||||
|
||||
redCircle.draw();
|
||||
greenCircle.draw();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建桥接实现接口
|
||||
///
|
||||
abstract class DrawAPI {
|
||||
void drawCircle(int radius, int x, int y);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 DrawAPI 接口的实体桥接实现类
|
||||
///
|
||||
class RedCircle implements DrawAPI {
|
||||
@override
|
||||
void drawCircle(int radius, int x, int y) {
|
||||
print("Drawing Circle[ color: red, radius: $radius"
|
||||
", x: $x, y:$y]");
|
||||
}
|
||||
}
|
||||
|
||||
class GreenCircle implements DrawAPI {
|
||||
@override
|
||||
void drawCircle(int radius, int x, int y) {
|
||||
print("Drawing Circle[ color: green, radius: $radius"
|
||||
", x: $x, y:$y]");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 使用 DrawAPI 接口创建抽象类 Shape
|
||||
///
|
||||
abstract class Shape {
|
||||
DrawAPI _drawAPI;
|
||||
Shape(this._drawAPI);
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 Shape 接口的实体类
|
||||
///
|
||||
class Circle extends Shape {
|
||||
int _x, _y, _radius;
|
||||
|
||||
Circle(this._x, this._y, this._radius, DrawAPI drawAPI) : super(drawAPI);
|
||||
|
||||
void draw() {
|
||||
_drawAPI.drawCircle(_radius, _x, _y);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
过滤器模式(Filter Pattern)
|
||||
|
||||
允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。
|
||||
这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
List<Person> persons = List<Person>();
|
||||
|
||||
persons.add(Person("Robert", "Male", "Single"));
|
||||
persons.add(Person("John", "Male", "Married"));
|
||||
persons.add(Person("Laura", "Female", "Married"));
|
||||
persons.add(Person("Diana", "Female", "Single"));
|
||||
persons.add(Person("Mike", "Male", "Single"));
|
||||
persons.add(Person("Bobby", "Male", "Single"));
|
||||
|
||||
Filter male = MaleFilter();
|
||||
Filter female = FemaleFilter();
|
||||
Filter single = SingleFilter();
|
||||
Filter singleMale = AndFilter(single, male);
|
||||
Filter singleOrFemale = OrFilter(single, female);
|
||||
|
||||
print("Males: ");
|
||||
male.filter(persons).forEach((p) => print(p));
|
||||
|
||||
print("\nFemales: ");
|
||||
female.filter(persons).forEach((p) => print(p));
|
||||
|
||||
print("\nSingle Males: ");
|
||||
singleMale.filter(persons).forEach((p) => print(p));
|
||||
|
||||
print("\nSingle Or Females: ");
|
||||
singleOrFemale.filter(persons).forEach((p) => print(p));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个类,在该类上应用过滤器
|
||||
///
|
||||
class Person {
|
||||
String name;
|
||||
String gender;
|
||||
String maritalStatus;
|
||||
|
||||
Person(this.name, this.gender, this.maritalStatus);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Person[name="$name", gender="$gender", maritalStatus="$maritalStatus"]';
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个过滤器接口
|
||||
///
|
||||
abstract class Filter {
|
||||
List<Person> filter(List<Person> persons);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 Filter 接口的实体类
|
||||
///
|
||||
class MaleFilter implements Filter {
|
||||
@override
|
||||
List<Person> filter(List<Person> persons) {
|
||||
List<Person> personList = List<Person>();
|
||||
for (Person person in persons) {
|
||||
if (person.gender.toUpperCase() == "MALE") {
|
||||
personList.add(person);
|
||||
}
|
||||
}
|
||||
return personList;
|
||||
}
|
||||
}
|
||||
|
||||
class FemaleFilter implements Filter {
|
||||
@override
|
||||
List<Person> filter(List<Person> persons) {
|
||||
List<Person> personList = List<Person>();
|
||||
for (Person person in persons) {
|
||||
if (person.gender.toUpperCase() == "FEMALE") {
|
||||
personList.add(person);
|
||||
}
|
||||
}
|
||||
return personList;
|
||||
}
|
||||
}
|
||||
|
||||
class SingleFilter implements Filter {
|
||||
@override
|
||||
List<Person> filter(List<Person> persons) {
|
||||
List<Person> personList = List<Person>();
|
||||
for (Person person in persons) {
|
||||
if (person.maritalStatus.toUpperCase() == "SINGLE") {
|
||||
personList.add(person);
|
||||
}
|
||||
}
|
||||
return personList;
|
||||
}
|
||||
}
|
||||
|
||||
class AndFilter implements Filter {
|
||||
Filter _filter1;
|
||||
Filter _filter2;
|
||||
|
||||
AndFilter(this._filter1, this._filter2);
|
||||
|
||||
@override
|
||||
List<Person> filter(List<Person> persons) {
|
||||
List<Person> personList = _filter1.filter(persons);
|
||||
return _filter2.filter(personList);
|
||||
}
|
||||
}
|
||||
|
||||
class OrFilter implements Filter {
|
||||
Filter _filter1;
|
||||
Filter _filter2;
|
||||
|
||||
OrFilter(this._filter1, this._filter2);
|
||||
|
||||
@override
|
||||
List<Person> filter(List<Person> persons) {
|
||||
List<Person> personList1 = _filter1.filter(persons);
|
||||
List<Person> personList2 = _filter1.filter(persons);
|
||||
|
||||
for (Person person in personList2) {
|
||||
if (!personList1.contains(person)) {
|
||||
personList1.add(person);
|
||||
}
|
||||
}
|
||||
return personList1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
组合模式(Composite Pattern)
|
||||
|
||||
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
|
||||
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
|
||||
何时使用:
|
||||
1、您想表示对象的部分-整体层次结构(树形结构)。
|
||||
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
|
||||
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Employee ceo = new Employee("John", "CEO", 30000);
|
||||
|
||||
Employee headSales = new Employee("Robert", "Head Sales", 20000);
|
||||
Employee headMarketing = new Employee("Michel", "Head Marketing", 20000);
|
||||
|
||||
Employee clerk1 = new Employee("Laura", "Marketing", 10000);
|
||||
Employee clerk2 = new Employee("Bob", "Marketing", 10000);
|
||||
|
||||
Employee salesExecutive1 = new Employee("Richard", "Sales", 10000);
|
||||
Employee salesExecutive2 = new Employee("Rob", "Sales", 10000);
|
||||
|
||||
ceo.add(headSales);
|
||||
ceo.add(headMarketing);
|
||||
|
||||
headSales.add(salesExecutive1);
|
||||
headSales.add(salesExecutive2);
|
||||
|
||||
headMarketing.add(clerk1);
|
||||
headMarketing.add(clerk2);
|
||||
|
||||
//打印该组织的所有员工
|
||||
print(ceo);
|
||||
for (Employee headEmployee in ceo.getSubordinates()) {
|
||||
print(' $headEmployee');
|
||||
for (Employee employee in headEmployee.getSubordinates()) {
|
||||
print(' $employee');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建 Employee 类,该类带有 Employee 对象的列表
|
||||
///
|
||||
class Employee {
|
||||
String name;
|
||||
String dept;
|
||||
int salary;
|
||||
List<Employee> subordinates;
|
||||
|
||||
//构造函数
|
||||
Employee(this.name, this.dept, this.salary) {
|
||||
subordinates = List<Employee>();
|
||||
}
|
||||
|
||||
void add(Employee e) {
|
||||
subordinates.add(e);
|
||||
}
|
||||
|
||||
void remove(Employee e) {
|
||||
subordinates.remove(e);
|
||||
}
|
||||
|
||||
List<Employee> getSubordinates() {
|
||||
return subordinates;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Employee [ name="$name", dept="$dept", salary="$salary" ]';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
装饰器模式(Decorator Pattern)
|
||||
|
||||
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
|
||||
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
|
||||
何时使用:在不想增加很多子类的情况下扩展类。
|
||||
如何解决:将具体功能职责划分,同时继承装饰者模式。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Shape circle = new Circle();
|
||||
|
||||
Shape redCircle = new RedShapeDecorator(new Circle());
|
||||
Shape redRectangle = new RedShapeDecorator(new Rectangle());
|
||||
|
||||
print("Circle with normal border");
|
||||
circle.draw();
|
||||
|
||||
print("\nCircle of red border");
|
||||
redCircle.draw();
|
||||
|
||||
print("\nRectangle of red border");
|
||||
redRectangle.draw();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Shape {
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Rectangle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Shape: Rectangle");
|
||||
}
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Shape: Circle");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 Shape 接口的抽象装饰类
|
||||
///
|
||||
abstract class ShapeDecorator implements Shape {
|
||||
Shape _decoratedShape;
|
||||
|
||||
ShapeDecorator(this._decoratedShape);
|
||||
|
||||
void draw() {
|
||||
_decoratedShape.draw();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了 ShapeDecorator 类的实体装饰类
|
||||
///
|
||||
class RedShapeDecorator extends ShapeDecorator {
|
||||
RedShapeDecorator(Shape decoratedShape) : super(decoratedShape);
|
||||
|
||||
@override
|
||||
void draw() {
|
||||
_decoratedShape.draw();
|
||||
setRedBorder(_decoratedShape);
|
||||
}
|
||||
|
||||
void setRedBorder(Shape decoratedShape) {
|
||||
print("Border Color: Red");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
外观模式(Facade Pattern)
|
||||
|
||||
意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
|
||||
主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。
|
||||
何时使用:
|
||||
1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。
|
||||
2、定义系统的入口。
|
||||
如何解决:客户端不与系统耦合,外观类与系统耦合。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
ShapeMaker shapeMaker = new ShapeMaker();
|
||||
shapeMaker.drawCircle();
|
||||
shapeMaker.drawRectangle();
|
||||
shapeMaker.drawSquare();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Shape {
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Rectangle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Rectangle::draw()");
|
||||
}
|
||||
}
|
||||
|
||||
class Square implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Square::draw()");
|
||||
}
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
@override
|
||||
void draw() {
|
||||
print("Circle::draw()");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个外观类
|
||||
///
|
||||
class ShapeMaker {
|
||||
Shape circle;
|
||||
Shape rectangle;
|
||||
Shape square;
|
||||
|
||||
ShapeMaker() {
|
||||
circle = Circle();
|
||||
rectangle = Rectangle();
|
||||
square = Square();
|
||||
}
|
||||
|
||||
void drawCircle() {
|
||||
circle.draw();
|
||||
}
|
||||
|
||||
void drawRectangle() {
|
||||
rectangle.draw();
|
||||
}
|
||||
|
||||
void drawSquare() {
|
||||
square.draw();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
享元模式(Flyweight Pattern)
|
||||
|
||||
意图:运用共享技术有效地支持大量细粒度的对象。
|
||||
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
|
||||
何时使用:
|
||||
1、系统中有大量对象。
|
||||
2、这些对象消耗大量内存。
|
||||
3、这些对象的状态大部分可以外部化。
|
||||
4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。
|
||||
5、系统不依赖于这些对象身份,这些对象是不可分辨的。
|
||||
如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
main(List<String> args) {
|
||||
final List<String> colors = ["Red", "Green", "Blue", "White", "Black"];
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
Circle circle =
|
||||
ShapeFactory.getCircle(colors[Random().nextInt(colors.length)]);
|
||||
circle.x = Random().nextInt(100);
|
||||
circle.y = Random().nextInt(100);
|
||||
circle.radius = 100;
|
||||
circle.draw();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Shape {
|
||||
void draw();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class Circle implements Shape {
|
||||
String color;
|
||||
int x;
|
||||
int y;
|
||||
int radius;
|
||||
|
||||
Circle(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@override
|
||||
void draw() {
|
||||
print("Circle: Draw() [Color : $color, x : $x, y :$y, radius :$radius");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个工厂,生成基于给定信息的实体类的对象
|
||||
///
|
||||
class ShapeFactory {
|
||||
static final Map<String, Shape> circleMap = Map();
|
||||
|
||||
static Shape getCircle(String color) {
|
||||
Circle circle = circleMap[color] as Circle;
|
||||
|
||||
if (circle == null) {
|
||||
circle = new Circle(color);
|
||||
circleMap[color] = circle;
|
||||
print("Creating circle of color : $color");
|
||||
}
|
||||
return circle;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
代理模式(Proxy Pattern)
|
||||
|
||||
意图:为其他对象提供一种代理以控制对这个对象的访问。
|
||||
主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
|
||||
何时使用:想在访问一个类时做一些控制。
|
||||
如何解决:增加中间层。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Image image = new ProxyImage("dart_logo.png");
|
||||
|
||||
// 图像将从磁盘加载
|
||||
image.display();
|
||||
// 图像不需要从磁盘加载
|
||||
image.display();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Image {
|
||||
void display();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class RealImage implements Image {
|
||||
String fileName;
|
||||
|
||||
RealImage(this.fileName) {
|
||||
loadFromDisk(fileName);
|
||||
}
|
||||
|
||||
@override
|
||||
void display() {
|
||||
print("Displaying $fileName");
|
||||
}
|
||||
|
||||
void loadFromDisk(String fileName) {
|
||||
print("Loading $fileName");
|
||||
}
|
||||
}
|
||||
|
||||
class ProxyImage implements Image {
|
||||
RealImage realImage;
|
||||
String fileName;
|
||||
|
||||
ProxyImage(this.fileName);
|
||||
|
||||
@override
|
||||
void display() {
|
||||
if (realImage == null) {
|
||||
realImage = RealImage(fileName);
|
||||
}
|
||||
realImage.display();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
责任链模式(Chain of Responsibility Pattern)
|
||||
|
||||
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
|
||||
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
|
||||
何时使用:在处理消息的时候以过滤很多道。
|
||||
如何解决:拦截的类都实现统一接口。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
AbstractLogger loggerChain = LoggerFactory.getChainOfLoggers();
|
||||
|
||||
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
|
||||
loggerChain.logMessage(
|
||||
AbstractLogger.DEBUG, "This is a debug level information.");
|
||||
loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建抽象的记录器类
|
||||
///
|
||||
abstract class AbstractLogger {
|
||||
static int INFO = 1;
|
||||
static int DEBUG = 2;
|
||||
static int ERROR = 3;
|
||||
|
||||
int _level;
|
||||
|
||||
//责任链中的下一个元素
|
||||
AbstractLogger _nextLogger;
|
||||
|
||||
void setNextLogger(AbstractLogger nextLogger) {
|
||||
this._nextLogger = nextLogger;
|
||||
}
|
||||
|
||||
void logMessage(int level, String message) {
|
||||
if (this._level <= level) {
|
||||
write(message);
|
||||
}
|
||||
if (_nextLogger != null) {
|
||||
_nextLogger.logMessage(level, message);
|
||||
}
|
||||
}
|
||||
|
||||
void write(String message);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了该记录器类的实体类
|
||||
///
|
||||
class ConsoleLogger extends AbstractLogger {
|
||||
ConsoleLogger(int level) {
|
||||
this._level = level;
|
||||
}
|
||||
|
||||
@override
|
||||
void write(String message) {
|
||||
print("Standard Console::Logger: $message");
|
||||
}
|
||||
}
|
||||
|
||||
class ErrorLogger extends AbstractLogger {
|
||||
ErrorLogger(int level) {
|
||||
this._level = level;
|
||||
}
|
||||
|
||||
@override
|
||||
void write(String message) {
|
||||
print("Error Console::Logger: $message");
|
||||
}
|
||||
}
|
||||
|
||||
class FileLogger extends AbstractLogger {
|
||||
FileLogger(int level) {
|
||||
this._level = level;
|
||||
}
|
||||
|
||||
@override
|
||||
void write(String message) {
|
||||
print("File::Logger: $message");
|
||||
}
|
||||
}
|
||||
|
||||
class LoggerFactory {
|
||||
static AbstractLogger getChainOfLoggers() {
|
||||
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
|
||||
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
|
||||
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
|
||||
|
||||
errorLogger.setNextLogger(fileLogger);
|
||||
fileLogger.setNextLogger(consoleLogger);
|
||||
|
||||
return errorLogger;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
命令模式(Command Pattern)
|
||||
|
||||
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
|
||||
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
|
||||
何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
|
||||
如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Stock abcStock = new Stock();
|
||||
|
||||
BuyStock buyStockOrder = new BuyStock(abcStock);
|
||||
SellStock sellStockOrder = new SellStock(abcStock);
|
||||
|
||||
Broker broker = new Broker();
|
||||
broker.takeOrder(buyStockOrder);
|
||||
broker.takeOrder(sellStockOrder);
|
||||
|
||||
broker.placeOrders();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个命令接口
|
||||
///
|
||||
abstract class Order {
|
||||
void execute();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建一个请求类
|
||||
///
|
||||
class Stock {
|
||||
String name = "ABC";
|
||||
int quantity = 10;
|
||||
|
||||
void buy() {
|
||||
print("Stock [ Name: $name, Quantity: $quantity ] bought");
|
||||
}
|
||||
|
||||
void sell() {
|
||||
print("Stock [ Name: $name, Quantity: $quantity ] sold");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 Order 接口的实体类
|
||||
///
|
||||
class BuyStock implements Order {
|
||||
Stock abcStock;
|
||||
|
||||
BuyStock(this.abcStock);
|
||||
|
||||
void execute() {
|
||||
abcStock.buy();
|
||||
}
|
||||
}
|
||||
|
||||
class SellStock implements Order {
|
||||
Stock abcStock;
|
||||
|
||||
SellStock(this.abcStock);
|
||||
|
||||
void execute() {
|
||||
abcStock.sell();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建命令调用类
|
||||
///
|
||||
class Broker {
|
||||
List<Order> orderList = new List<Order>();
|
||||
|
||||
void takeOrder(Order order) {
|
||||
orderList.add(order);
|
||||
}
|
||||
|
||||
void placeOrders() {
|
||||
for (Order order in orderList) {
|
||||
order.execute();
|
||||
}
|
||||
orderList.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
解释器模式(Interpreter Pattern)
|
||||
|
||||
意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
|
||||
主要解决:对于一些固定文法构建一个解释句子的解释器。
|
||||
何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
|
||||
如何解决:构建语法树,定义终结符与非终结符。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Expression robert = TerminalExpression("Robert");
|
||||
Expression john = TerminalExpression("John");
|
||||
Expression isMale = OrExpression(robert, john);
|
||||
print("John is male? ${isMale.interpret('john')}");
|
||||
|
||||
Expression julie = TerminalExpression("Julie");
|
||||
Expression married = TerminalExpression("Married");
|
||||
Expression isMarriedWoman = AndExpression(julie, married);
|
||||
print(
|
||||
"Julie is a married women? ${isMarriedWoman.interpret('Married Julie')}");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个表达式接口
|
||||
///
|
||||
abstract class Expression {
|
||||
bool interpret(String context);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了上述接口的实体类
|
||||
///
|
||||
class TerminalExpression implements Expression {
|
||||
String _data;
|
||||
|
||||
TerminalExpression(this._data);
|
||||
|
||||
@override
|
||||
bool interpret(String context) {
|
||||
if (context.contains(_data)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class OrExpression implements Expression {
|
||||
Expression _expr1;
|
||||
Expression _expr2;
|
||||
|
||||
OrExpression(this._expr1, this._expr2);
|
||||
|
||||
@override
|
||||
bool interpret(String context) {
|
||||
return _expr1.interpret(context) || _expr2.interpret(context);
|
||||
}
|
||||
}
|
||||
|
||||
class AndExpression implements Expression {
|
||||
Expression _expr1;
|
||||
Expression _expr2;
|
||||
|
||||
AndExpression(this._expr1, this._expr2);
|
||||
|
||||
@override
|
||||
bool interpret(String context) {
|
||||
return _expr1.interpret(context) && _expr2.interpret(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
迭代器模式(Iterator Pattern)
|
||||
|
||||
意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
|
||||
主要解决:不同的方式来遍历整个整合对象。
|
||||
何时使用:遍历一个聚合对象。
|
||||
如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
NameRepository namesRepository = new NameRepository();
|
||||
|
||||
for (Iterator iter = namesRepository.getIterator(); iter.hasNext();) {
|
||||
String name = iter.next();
|
||||
print("Name : $name");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建接口
|
||||
///
|
||||
abstract class Iterator {
|
||||
bool hasNext();
|
||||
Object next();
|
||||
}
|
||||
|
||||
abstract class Container {
|
||||
Iterator getIterator();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了 Container 接口的实体类。实现了 Iterator 接口的类 NameIterator
|
||||
///
|
||||
class NameRepository implements Container {
|
||||
List<String> names = ["Robert", "John", "Julie", "Lora"];
|
||||
|
||||
@override
|
||||
Iterator getIterator() {
|
||||
return NameIterator(names);
|
||||
}
|
||||
}
|
||||
|
||||
class NameIterator implements Iterator {
|
||||
List<String> _names;
|
||||
int _index = 0;
|
||||
|
||||
NameIterator(this._names);
|
||||
|
||||
@override
|
||||
bool hasNext() {
|
||||
if (_index < _names.length) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Object next() {
|
||||
if (this.hasNext()) {
|
||||
return _names[_index++];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
中介者模式(Mediator Pattern)
|
||||
|
||||
意图:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
|
||||
主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
|
||||
何时使用:多个类相互耦合,形成了网状结构。
|
||||
如何解决:将上述网状结构分离为星型结构。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
User robert = User("Robert");
|
||||
User john = User("John");
|
||||
|
||||
robert.sendMessage("Hi! John!");
|
||||
john.sendMessage("Hello! Robert!");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建中介类
|
||||
///
|
||||
class ChatRoom {
|
||||
static void showMessage(User user, String message) {
|
||||
print("[${user.name}]: $message");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 user 类
|
||||
///
|
||||
class User {
|
||||
String name;
|
||||
|
||||
User(this.name);
|
||||
|
||||
void sendMessage(String message) {
|
||||
ChatRoom.showMessage(this, message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
备忘录模式(Memento Pattern)
|
||||
|
||||
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
|
||||
主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
|
||||
何时使用:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
|
||||
如何解决:通过一个备忘录类专门存储对象状态。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Originator originator = Originator();
|
||||
CareTaker careTaker = CareTaker();
|
||||
originator.setState("State #1");
|
||||
originator.setState("State #2");
|
||||
careTaker.add(originator.saveStateToMemento());
|
||||
|
||||
originator.setState("State #3");
|
||||
careTaker.add(originator.saveStateToMemento());
|
||||
|
||||
originator.setState("State #4");
|
||||
print("Current State: ${originator.getState()}");
|
||||
|
||||
originator.getStateFromMemento(careTaker.get(0));
|
||||
print("First saved State: ${originator.getState()}");
|
||||
|
||||
originator.getStateFromMemento(careTaker.get(1));
|
||||
print("Second saved State: ${originator.getState()}");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建 Memento 类
|
||||
///
|
||||
class Memento {
|
||||
String _state;
|
||||
|
||||
Memento(this._state);
|
||||
|
||||
String getState() {
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 Originator 类
|
||||
///
|
||||
class Originator {
|
||||
String _state;
|
||||
|
||||
void setState(String state) {
|
||||
this._state = state;
|
||||
}
|
||||
|
||||
String getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
Memento saveStateToMemento() {
|
||||
return Memento(_state);
|
||||
}
|
||||
|
||||
void getStateFromMemento(Memento memento) {
|
||||
_state = memento.getState();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 CareTaker 类
|
||||
///
|
||||
class CareTaker {
|
||||
List<Memento> _mementoList = List<Memento>();
|
||||
|
||||
void add(Memento state) {
|
||||
_mementoList.add(state);
|
||||
}
|
||||
|
||||
Memento get(int index) {
|
||||
return _mementoList[index];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
观察者模式(Observer Pattern)
|
||||
|
||||
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
|
||||
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
|
||||
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
|
||||
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Subject subject = Subject();
|
||||
HexaObserver(subject);
|
||||
OctalObserver(subject);
|
||||
BinaryObserver(subject);
|
||||
|
||||
print("First state change: 15");
|
||||
subject.setState(15);
|
||||
|
||||
print("\nSecond state change: 10");
|
||||
subject.setState(10);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建 Subject 类
|
||||
///
|
||||
class Subject {
|
||||
List<Observer> _observers = List<Observer>();
|
||||
int _state;
|
||||
|
||||
int getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
void setState(int state) {
|
||||
this._state = state;
|
||||
notifyAllObservers();
|
||||
}
|
||||
|
||||
void attach(Observer observer) {
|
||||
_observers.add(observer);
|
||||
}
|
||||
|
||||
void notifyAllObservers() {
|
||||
for (Observer observer in _observers) {
|
||||
observer.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 Observer 类
|
||||
///
|
||||
abstract class Observer {
|
||||
Subject _subject;
|
||||
void update();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实体观察者类
|
||||
///
|
||||
class BinaryObserver extends Observer {
|
||||
BinaryObserver(Subject subject) {
|
||||
this._subject = subject;
|
||||
this._subject.attach(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void update() {
|
||||
print("Binary String: ${_subject.getState().toRadixString(2)}");
|
||||
}
|
||||
}
|
||||
|
||||
class OctalObserver extends Observer {
|
||||
OctalObserver(Subject subject) {
|
||||
this._subject = subject;
|
||||
this._subject.attach(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void update() {
|
||||
print("Octal String: ${_subject.getState()}");
|
||||
}
|
||||
}
|
||||
|
||||
class HexaObserver extends Observer {
|
||||
HexaObserver(Subject subject) {
|
||||
this._subject = subject;
|
||||
this._subject.attach(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void update() {
|
||||
print("Hex String: ${_subject.getState().toRadixString(16)}");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
状态模式(State Pattern)
|
||||
|
||||
意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
|
||||
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
|
||||
何时使用:代码中包含大量与对象状态有关的条件语句。
|
||||
如何解决:将各种具体的状态类抽象出来。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Context context = Context();
|
||||
|
||||
StartState startState = StartState();
|
||||
startState.doAction(context);
|
||||
print(context.state);
|
||||
|
||||
StopState stopState = new StopState();
|
||||
stopState.doAction(context);
|
||||
print(context.state);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class State {
|
||||
void doAction(Context context);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 Context 类
|
||||
///
|
||||
class Context {
|
||||
State state = null;
|
||||
|
||||
Context();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class StartState implements State {
|
||||
void doAction(Context context) {
|
||||
print("Player is in start state");
|
||||
context.state = this;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Start State";
|
||||
}
|
||||
}
|
||||
|
||||
class StopState implements State {
|
||||
void doAction(Context context) {
|
||||
print("Player is in stop state");
|
||||
context.state = this;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Stop State";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
空对象模式(Null Object Pattern)
|
||||
|
||||
一个空对象取代 NULL 对象实例的检查。
|
||||
Null 对象不是检查空值,而是反应一个不做任何动作的关系。
|
||||
这样的 Null 对象也可以在数据不可用的时候提供默认的行为。
|
||||
在空对象模式中,我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类,还创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
|
||||
AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
|
||||
AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
|
||||
AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");
|
||||
|
||||
print("Customers");
|
||||
print(customer1.getName());
|
||||
print(customer2.getName());
|
||||
print(customer3.getName());
|
||||
print(customer4.getName());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个抽象类
|
||||
///
|
||||
abstract class AbstractCustomer {
|
||||
String _name;
|
||||
bool isNil();
|
||||
String getName();
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了上述类的实体类
|
||||
///
|
||||
class RealCustomer extends AbstractCustomer {
|
||||
RealCustomer(String name) {
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
@override
|
||||
String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@override
|
||||
bool isNil() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class NullCustomer extends AbstractCustomer {
|
||||
@override
|
||||
String getName() {
|
||||
return "Not Available in Customer Database";
|
||||
}
|
||||
|
||||
@override
|
||||
bool isNil() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 CustomerFactory 类
|
||||
///
|
||||
class CustomerFactory {
|
||||
static final List<String> _names = ["Rob", "Joe", "Julie"];
|
||||
|
||||
static AbstractCustomer getCustomer(String name) {
|
||||
for (int i = 0; i < _names.length; i++) {
|
||||
if (_names[i] == name) {
|
||||
return new RealCustomer(name);
|
||||
}
|
||||
}
|
||||
return new NullCustomer();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
策略模式(Strategy Pattern)
|
||||
|
||||
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
|
||||
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
|
||||
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
|
||||
如何解决:将这些算法封装成一个一个的类,任意地替换。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Context context = new Context(new OperationAdd());
|
||||
print("10 + 5 = ${context.executeStrategy(10, 5)}");
|
||||
|
||||
context = new Context(new OperationSubstract());
|
||||
print("10 - 5 = ${context.executeStrategy(10, 5)}");
|
||||
|
||||
context = new Context(new OperationMultiply());
|
||||
print("10 * 5 = ${context.executeStrategy(10, 5)}");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个接口
|
||||
///
|
||||
abstract class Strategy {
|
||||
int doOperation(int num1, int num2);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现接口的实体类
|
||||
///
|
||||
class OperationAdd implements Strategy {
|
||||
@override
|
||||
int doOperation(int num1, int num2) {
|
||||
return num1 + num2;
|
||||
}
|
||||
}
|
||||
|
||||
class OperationSubstract implements Strategy {
|
||||
@override
|
||||
int doOperation(int num1, int num2) {
|
||||
return num1 - num2;
|
||||
}
|
||||
}
|
||||
|
||||
class OperationMultiply implements Strategy {
|
||||
@override
|
||||
int doOperation(int num1, int num2) {
|
||||
return num1 * num2;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建 Context 类
|
||||
///
|
||||
class Context {
|
||||
Strategy _strategy;
|
||||
|
||||
Context(this._strategy);
|
||||
|
||||
int executeStrategy(int num1, int num2) {
|
||||
return _strategy.doOperation(num1, num2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
模板模式(Template Pattern)
|
||||
|
||||
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
|
||||
主要解决:一些方法通用,却在每一个子类都重新写了这一方法。
|
||||
何时使用:有一些通用的方法。
|
||||
如何解决:将这些通用算法抽象出来。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Game game = new Cricket();
|
||||
game.play();
|
||||
print('');
|
||||
game = new Football();
|
||||
game.play();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建一个抽象类
|
||||
///
|
||||
abstract class Game {
|
||||
void initialize();
|
||||
void startPlay();
|
||||
void endPlay();
|
||||
|
||||
//模板
|
||||
void play() {
|
||||
//初始化游戏
|
||||
initialize();
|
||||
|
||||
//开始游戏
|
||||
startPlay();
|
||||
|
||||
//结束游戏
|
||||
endPlay();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了上述类的实体类
|
||||
///
|
||||
class Cricket extends Game {
|
||||
@override
|
||||
void endPlay() {
|
||||
print("Cricket Game Finished!");
|
||||
}
|
||||
|
||||
@override
|
||||
void initialize() {
|
||||
print("Cricket Game Initialized! Start playing.");
|
||||
}
|
||||
|
||||
@override
|
||||
void startPlay() {
|
||||
print("Cricket Game Started. Enjoy the game!");
|
||||
}
|
||||
}
|
||||
|
||||
class Football extends Game {
|
||||
@override
|
||||
void endPlay() {
|
||||
print("Football Game Finished!");
|
||||
}
|
||||
|
||||
@override
|
||||
void initialize() {
|
||||
print("Football Game Initialized! Start playing.");
|
||||
}
|
||||
|
||||
@override
|
||||
void startPlay() {
|
||||
print("Football Game Started. Enjoy the game!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
访问者模式(Visitor Pattern)
|
||||
|
||||
意图:主要将数据结构与数据操作分离。
|
||||
主要解决:稳定的数据结构和易变的操作耦合问题。
|
||||
何时使用:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,使用访问者模式将这些封装到类中。
|
||||
如何解决:在被访问的类里面加一个对外提供接待访问者的接口。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
ComputerPart computer = Computer();
|
||||
computer.accept(ComputerPartDisplayVisitor());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 定义一个表示元素的接口
|
||||
///
|
||||
abstract class ComputerPart {
|
||||
void accept(ComputerPartVisitor computerPartVisitor);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建扩展了上述类的实体类
|
||||
///
|
||||
class Keyboard implements ComputerPart {
|
||||
@override
|
||||
void accept(ComputerPartVisitor computerPartVisitor) {
|
||||
computerPartVisitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
class Monitor implements ComputerPart {
|
||||
@override
|
||||
void accept(ComputerPartVisitor computerPartVisitor) {
|
||||
computerPartVisitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
class Mouse implements ComputerPart {
|
||||
@override
|
||||
void accept(ComputerPartVisitor computerPartVisitor) {
|
||||
computerPartVisitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
class Computer implements ComputerPart {
|
||||
List<ComputerPart> _parts;
|
||||
|
||||
Computer() {
|
||||
_parts = [Mouse(), Keyboard(), Monitor()];
|
||||
}
|
||||
|
||||
@override
|
||||
void accept(ComputerPartVisitor computerPartVisitor) {
|
||||
for (int i = 0; i < _parts.length; i++) {
|
||||
_parts[i].accept(computerPartVisitor);
|
||||
}
|
||||
computerPartVisitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 定义一个表示访问者的接口
|
||||
///
|
||||
abstract class ComputerPartVisitor {
|
||||
void visit(dynamic part);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了上述类的实体访问者
|
||||
///
|
||||
class ComputerPartDisplayVisitor implements ComputerPartVisitor {
|
||||
@override
|
||||
void visit(part) {
|
||||
if (part is Computer) {
|
||||
print("Displaying Computer.");
|
||||
} else if (part is Mouse) {
|
||||
print("Displaying Mouse.");
|
||||
} else if (part is Keyboard) {
|
||||
print("Displaying Keyboard.");
|
||||
} else if (part is Monitor) {
|
||||
print("Displaying Monitor.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
Model-View-Controller(模型-视图-控制器) 模式
|
||||
|
||||
Model(模型) - 模型代表一个存取数据的对象。它也可以带有逻辑,在数据变化时更新控制器。
|
||||
View(视图) - 视图代表模型包含的数据的可视化。
|
||||
Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
Student student = new Student();
|
||||
student.name = "Robert";
|
||||
student.rollNo = "10";
|
||||
|
||||
//创建一个视图:把学生详细信息输出到控制台
|
||||
StudentView view = new StudentView();
|
||||
|
||||
StudentController controller = new StudentController(student, view);
|
||||
controller.updateView();
|
||||
|
||||
//更新模型数据
|
||||
controller.setStudentName("John");
|
||||
controller.updateView();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建模型
|
||||
///
|
||||
class Student {
|
||||
String rollNo;
|
||||
String name;
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建视图
|
||||
///
|
||||
class StudentView {
|
||||
void printStudentDetails(String studentName, String studentRollNo) {
|
||||
print("Student: \nName: $studentName\n Roll No: $studentRollNo");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建控制器
|
||||
///
|
||||
class StudentController {
|
||||
Student _model;
|
||||
StudentView _view;
|
||||
|
||||
StudentController(this._model, this._view);
|
||||
|
||||
void setStudentName(String name) {
|
||||
_model.name = name;
|
||||
}
|
||||
|
||||
String getStudentName() {
|
||||
return _model.name;
|
||||
}
|
||||
|
||||
void setStudentRollNo(String rollNo) {
|
||||
_model.rollNo = rollNo;
|
||||
}
|
||||
|
||||
String getStudentRollNo() {
|
||||
return _model.rollNo;
|
||||
}
|
||||
|
||||
updateView() {
|
||||
_view.printStudentDetails(_model.name, _model.rollNo);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
数据访问对象模式(Data Access Object Pattern)
|
||||
|
||||
数据访问对象接口(Data Access Object Interface) - 该接口定义了在一个模型对象上要执行的标准操作。
|
||||
数据访问对象实体类(Data Access Object concrete class) - 该类实现了上述的接口。该类负责从数据源获取数据,数据源可以是数据库,也可以是 xml,或者是其他的存储机制。
|
||||
模型对象/数值对象(Model Object/Value Object) - 简单数值对象,包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
StudentDao studentDao = new StudentDaoImpl();
|
||||
|
||||
//输出所有的学生
|
||||
for (Student student in studentDao.getAllStudents()) {
|
||||
print("Student: [RollNo : ${student.rollNo}, Name : ${student.name} ]");
|
||||
}
|
||||
|
||||
//更新学生
|
||||
Student student = studentDao.getAllStudents()[0];
|
||||
student.name = "Michael";
|
||||
studentDao.updateStudent(student);
|
||||
|
||||
//获取学生
|
||||
studentDao.getStudent(0);
|
||||
print("Student: [RollNo : ${student.rollNo}, Name : ${student.name} ]");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建数值对象
|
||||
///
|
||||
class Student {
|
||||
int rollNo;
|
||||
String name;
|
||||
|
||||
Student(this.name, this.rollNo);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建数据访问对象接口
|
||||
///
|
||||
abstract class StudentDao {
|
||||
List<Student> getAllStudents();
|
||||
Student getStudent(int rollNo);
|
||||
void updateStudent(Student student);
|
||||
void deleteStudent(Student student);
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建实现了上述接口的实体类
|
||||
///
|
||||
class StudentDaoImpl implements StudentDao {
|
||||
//列表是当作一个数据库
|
||||
List<Student> _students;
|
||||
|
||||
StudentDaoImpl() {
|
||||
_students = List<Student>();
|
||||
Student student1 = Student("Robert", 0);
|
||||
Student student2 = Student("John", 1);
|
||||
_students.add(student1);
|
||||
_students.add(student2);
|
||||
}
|
||||
|
||||
@override
|
||||
void deleteStudent(Student student) {
|
||||
_students.remove(student.rollNo);
|
||||
print("Student: Roll No ${student.rollNo}, deleted from database");
|
||||
}
|
||||
|
||||
//从数据库中检索学生名单
|
||||
@override
|
||||
List<Student> getAllStudents() {
|
||||
return _students;
|
||||
}
|
||||
|
||||
@override
|
||||
Student getStudent(int rollNo) {
|
||||
return _students[rollNo];
|
||||
}
|
||||
|
||||
@override
|
||||
void updateStudent(Student student) {
|
||||
_students[student.rollNo]?.name = student.name;
|
||||
print("Student: Roll No ${student.rollNo}, updated in the database");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
前端控制器模式(Front Controller Pattern)
|
||||
|
||||
前端控制器(Front Controller) - 处理应用程序所有类型请求的单个处理程序,应用程序可以是基于web的应用程序,也可以是非web的应用程序。
|
||||
调度器(Dispatcher) - 前端控制器可能使用一个调度器对象来调度请求到相应的具体处理程序。
|
||||
视图(View) - 视图是为请求而创建的对象。
|
||||
*/
|
||||
main(List<String> args) {
|
||||
// 用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。
|
||||
// 该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序
|
||||
FrontController frontController = new FrontController();
|
||||
frontController.dispatchRequest("HOME");
|
||||
frontController.dispatchRequest("STUDENT");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 创建视图
|
||||
///
|
||||
class HomeView {
|
||||
void show() {
|
||||
print("Displaying Home Page");
|
||||
}
|
||||
}
|
||||
|
||||
class StudentView {
|
||||
void show() {
|
||||
print("Displaying Student Page");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建调度器 Dispatcher
|
||||
///
|
||||
class Dispatcher {
|
||||
StudentView _studentView;
|
||||
HomeView _homeView;
|
||||
Dispatcher() {
|
||||
_studentView = StudentView();
|
||||
_homeView = HomeView();
|
||||
}
|
||||
|
||||
void dispatch(String request) {
|
||||
if (request.toUpperCase() == "STUDENT") {
|
||||
_studentView.show();
|
||||
} else {
|
||||
_homeView.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 创建前端控制器 FrontController
|
||||
///
|
||||
class FrontController {
|
||||
Dispatcher _dispatcher;
|
||||
|
||||
FrontController() {
|
||||
_dispatcher = Dispatcher();
|
||||
}
|
||||
|
||||
bool _isAuthenticUser() {
|
||||
print("User is authenticated successfully.");
|
||||
return true;
|
||||
}
|
||||
|
||||
void _trackRequest(String request) {
|
||||
print("Page requested: " + request);
|
||||
}
|
||||
|
||||
void dispatchRequest(String request) {
|
||||
//记录每一个请求
|
||||
_trackRequest(request);
|
||||
//对用户进行身份验证
|
||||
if (_isAuthenticUser()) {
|
||||
_dispatcher.dispatch(request);
|
||||
}
|
||||
}
|
||||
}
|
107
README.md
107
README.md
|
@ -1,36 +1,93 @@
|
|||
# dart_in_action
|
||||
# Dart语言入门
|
||||
|
||||
#### Description
|
||||
Dart语言入门教程,设计模式Dart语言版。
|
||||
## Dart语言介绍
|
||||
dart语言是由谷歌公司开发的网络编程语言,于2011年10月10日发布。可以通过官网进一步[了解Dart语言](https://www.dartlang.org/guides/language/language-tour)
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
## Dart开发环境安装和配置
|
||||
操作系统:Windows、macOS、Linux
|
||||
下载地址:https://flutter.dev/docs/development/tools/sdk/releases?tab=macos
|
||||
|
||||
#### Installation
|
||||
* 以macOS为例:解压缩到目录/Users/(macuser)/Dev/flutter/
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
* 配置:
|
||||
> vi ~/.bash_profile
|
||||
|
||||
#### Instructions
|
||||
* 编辑:
|
||||
```bash
|
||||
# 导出dart
|
||||
export DART_HOME=/Users/(macuser)/Dev/flutter/flutter/bin/cache/dart-sdk
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
# 导出flutter
|
||||
export FLUTTER_HOME=/Users/(macuser)/Dev/flutter/flutter
|
||||
export PUB_HOSTED_URL=https://pub.flutter-io.cn
|
||||
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
|
||||
|
||||
#### Contribution
|
||||
export PATH=$DART_HOME/bin:$FLUTTER_HOME/bin:(其他导出项)
|
||||
```
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
* 校验:
|
||||
> dart --version
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
## 配置编辑器:VS Code
|
||||
* 安装dart支持
|
||||
![安装dart](screenshots/dart.jpg)
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
* 安装代码运行插件
|
||||
![](screenshots/code_runner.jpg)
|
||||
![](screenshots/run.jpg)
|
||||
|
||||
* 配置debug
|
||||
![](screenshots/debug.jpg)
|
||||
|
||||
* 安装flutter(可选)
|
||||
![flutter](screenshots/flutter.jpg)
|
||||
|
||||
## 主要内容
|
||||
1. Hello World
|
||||
- 运行Dart代码
|
||||
- Dart语言介绍
|
||||
2. 内置数据类型
|
||||
- 内置数据类型
|
||||
- 变量定义
|
||||
3. 条件控制语句
|
||||
- IF ELSE
|
||||
- 条件表达式
|
||||
- Switch Case
|
||||
4. 循环
|
||||
- for
|
||||
- while
|
||||
- do ..while
|
||||
- break
|
||||
- continue
|
||||
- 高级用法
|
||||
5. 函数
|
||||
- 函数定义
|
||||
- 可选参数
|
||||
- 命名参数
|
||||
- 默认参数
|
||||
6. 异常处理
|
||||
- try ..on
|
||||
- try ..catch
|
||||
- try ..finally
|
||||
- 自定义异常
|
||||
7. 类和对象
|
||||
- 定义类
|
||||
- 类成员可见性
|
||||
- 属性
|
||||
- 构造函数
|
||||
- 自定义构造函数
|
||||
- 成员变量赋值
|
||||
8. 继承
|
||||
- 继承
|
||||
- extends、implements
|
||||
- 混入(mixin)
|
||||
9. Lambda表达式
|
||||
- Lambda Expression
|
||||
- 函数返回Function
|
||||
- 函数接收Function类型的参数
|
||||
10. 闭包
|
||||
11. 集合
|
||||
12. callable classes
|
||||
13. 设计模式(13-40)
|
||||
- 常用设计模式的Dart实现
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
main(List<String> args) {
|
||||
var intVar = 123;
|
||||
var strVar = "Hello";
|
||||
print("$intVar, $strVar");
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
Binary file not shown.
After Width: | Height: | Size: 160 KiB |
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
Binary file not shown.
After Width: | Height: | Size: 188 KiB |
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
Loading…
Reference in New Issue