C#從零開始_自學C#、Visual Studio實境秀 46/ Getting Started with C# Lesson 18~20 xU...



{

58:00 59:00 多型 (polymorphism) 是一種延伸自繼承 (inheritance) 的程式設計,使父類別 (superclass) 可以當作子類別 (subclass) 的通用型態 (type) 。 http://bit.ly/2vn03hb

1:40:00 因為 c# 是 a strongly-typed language 不想太拘於其 type 的嚴格性或拘謹 故有 多型 方便法門 開方便門 ;類似說是 a strongly-typed language 的補強或補救措施

1:03:00 當實值型別的變數轉換成物件時,即稱之為 Boxed。 當型別物件的變數轉換成實值型別時,即稱之為 Unboxed。 如需詳細資訊,請參閱 Boxing 和 Unboxing。 http://bit.ly/2uoRs99

1:04:00 object 通吃 就對了 object 型別在 .NET Framework 中是 Object 的別名。 在 C# 的統一型別系統中,所有類型 (預先定義和使用者定義的、參考型別和實值型別) 都會直接或間接繼承自 Object。 您可以將任何型別的值指派給 object 型別的變數。

1:09:00 大家對 C# 匿名類型的資訊了解嗎?🤗 此類型提供一個便利的方法,將一組唯讀屬性封裝成一個物件,而不需要事先明確定義類型;內文將以名為 Amount 和 Message 的屬性初始化匿名類型做示範。 http://bit.ly/2wpWeVh

anonymous type

1:30:00 Getting Started with xUnit.net (desktop)

{

Build the solution to ensure that the code compiles. Now that you've written the first test, we need a way to run it. Let's install the NuGet package with the console runner.

建置解決方案以確保程式碼已正確編譯。 現在您已寫下了第一個測試的內容,而我們需要用一種方法來運行它。 讓我們用主控台執行器來安裝NuGet套件。

Unlike the previous package (which added references to the unit testing framework), this package is what's known as a solution-level package. Instead of having assemblies to reference, it adds some tools in your solution folder.

1:55:00 We will use one of these tools—the console runner—to run your unit tests.

1:55:30 要開始來執行測試了;Run tests with the xUnit.net console runner

2:13:00 The console runner has several command line options, which include options for parallelization, test filtering, and result reporting. To learn more about the console runner options, run the console runner with no command line options.

要了解  console runner 的參數(options)用法 就直接執行  console runner 而不加引數

Write your first theory 可見 單元測試有 theories  facts 二種:You may have wondered why your first unit tests use an attribute named [Fact] rather than one with a more traditional name like Test. xUnit.net includes support for two different major types of unit tests: facts and theories. When describing the difference between facts and theories, we like to say:

Facts are tests which are always true. They test invariant conditions.

Theories are tests which are only true for a particular set of data.

2:42:00 類別庫 就要用 建置(build),不能用開始偵錯!

{

using Xunit;

namespace ClassLibrary1

{

public class Class1

{

[Fact]

public void PassingTest()

{

Assert.Equal(4, Add(2, 2));

}



[Fact]

public void FailingTest()

{

Assert.Equal(5, Add(2, 2));

}



int Add(int x, int y)

{

return x + y;

}



[Theory]

[InlineData(4) ]

[InlineData(2)]

[InlineData(3)]

[InlineData(5)]

void MyFirstTheory(int value)

{

Assert.True(IsOdd(value));



}



bool IsOdd(int value)

{

return value % 2 == 1;

}

}

}



}

2:45:40 Running tests with Visual Studio

2:54:00 xunit.runner.visualstudio

2:55:50 Test > Windows > Test Explorer(測試視窗)

2:57:00  Every time you build your project, the runner will discover unit tests in your project

因為是在類別庫中,所以都用 build 可能也是因為類別庫無法開始偵錯,所以用此方法測試,否則用偵錯的方式測試應該就可以了嘛

3:04:00 追蹤堆疊  the stack trace

}

使用 dotnet test 的 .NET Core 單元測試 http://bit.ly/2upqezh

{3:26:00 [Fact] 屬性會將方法表示為單一測試

執行 dotnet test 來建置測試和類別庫,然後執行測試

3:29:00 您可以使用 [Fact] 屬性將這些項目新增為新測試,但很快就會單調乏味。 因此,還有其他 xUnit 屬性,可讓您撰寫類似的測試套件。 [Theory] 屬性代表執行相同程式碼但有不同輸入引數的測試套件。 您可以使用 [InlineData] 屬性來指定這些輸入值。

繼續在主要程式庫中新增更多測試、更多理論和更多程式碼,以反覆執行。 您就可以得到測試的完成版和程式庫的完整實作。

您已建置好小型的程式庫和該程式庫的一組單元測試, 您已經將方案結構化,使新增套件和測試更順暢,因此您可以將大部分的時間和精力專注於解決應用程式的目標。

程式庫=類別庫=assemblies=.dll

3:33:40 測試都會用 Should 來命名  convention 有這個慣例

3:38:00 所以這個測試其實比較適合在 類別庫 或 程式庫中使用 好比在 應用程式裡的開始偵錯的功能一樣。

}



3:41:30 Lesson 19 of 20 Common Patterns and Antipatterns http://bit.ly/2u6Pk6u

{

Common C# Patterns and Antipatterns

Common approaches to solving similar problems are referred to as design patterns.

Common approaches to solving similar problems that often end up causing more problems than they solve are called antipatterns (or anti-patterns).

3:48:00  adapter, factory, repository, and strategy design patterns.

Singleton and Static Cling.

3:50:00 The Adapter Design Pattern

The goal of the Adapter design pattern is to convert one interface to another. Frequently this is to allow multiple different systems or objects to interact with one another.

大概都是一些程式設計的哲學、規範

3:54:00  Adapter interface <==> Adapter implementations

and write your own Adapter implementations for each provider.

These should be the only classes in your application that reference the provider-specific code - the rest of your application should work only with your adapters.

所以 Adapter implementations 其實就是一種 class 可以實作 interface 作為一個 Adapter

Adapter Design Pattern http://bit.ly/2vvN38x

Conform Classes To The Interface You Need

{

4:10:00 The Adapter Design Pattern, also known as the Wrapper, allows two classes to work together that otherwise would have incompatible interfaces.

In this case, this software design pattern maps particularly well to the real-world example of an electrical power adapter, which must be used to allow a device to use power.  For instance, most mobile devices today can be powered via some form of USB power, or via AC current.  However, in both cases there is no direct way for the device to plug into the wall or USB port.  The solution is an adapter.

所以 Adapter 又類似轉接器的概念或運作模式

都是一種設計的模型概念

Convert the interface of a class into another interface clients expect.  Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.



}

轉接頭

4:22:00 When creating your adapter interface, you're free to make whatever design decisions will make it easiest for your application to work with it.

更靈活化、更善於應變

Your adapter will need to avoid using any provider-specific types in its interface.

所以 adapter 一定是包括 classes 和 interfaces

4:32:00 With this design in place, you could accept an IPaymentProcessorAdapter anywhere you needed to process a payment.

as a property on a user or storefront object:設定成為執行個體的屬性 You could set it as a property on a user or storefront object to specify its payment preference.

一本萬利 靈活應變 好像千手千眼觀音 隨處變化 隨處現 隨眾生心,應所知量

Adapter 其實就是 interfaces 和 classes 的聚合體 也是像 interface 作為仲介一樣 作為代理人 5:09:00 專職代理人 也就是前面學到的 class 要盡分化、專一、專注在某些事務上



5:11:10 The Factory Design Pattern

5:18:00 可見 Adapter 就是新建一個專司專職的 class: it's going to need to create the appropriate adapter class

5:32:00 Typically this type will use the "Factory" suffix in its name



5:37:30 The Repository Design Pattern

Of course, when an order is placed and payment succeeds, the order needs to be stored somewhere. The Store itself could include logic for connecting to a database and executing commands against it to perform this logic, but, once more, that's an additional responsibility the store shouldn't take on for itself. Rather, some other class should have the responsibility of persistence (of Orders in this case).

There is a design pattern for encapsulating persistence operations behind a class with a collection-like interface, and it is called the Repository pattern.

就是把一個 class 的工作盡量單純化,把可以分割出去的工作,分權、分層負責出去

The goal of this pattern is to make working with external persistence mechanisms, like databases, as simple for the application code as working with a built-in collection would be.

You don't want the low-level details of connecting to a database to be in the middle of a high level business method on completing an order. At the very least, those details should be extracted into their own method.

However, there are likely to be many similar such methods, all concerned with the specifics of data access. It's far more cohesive to put these methods on classes whose specific responsibility is persistence. These are called repositories.

Now, the CompleteOrder method can simply refer to an instance of IOrderRepository:

5:56:00 CRUD

Repositories 專司其職

With such an abstraction in place, you can perform most data access operations from your business-level code without coupling it directly to any particular persistence implementation.

This also helps your business classes remain persistence ignorant (again, keeping them from being coupled to a particular persistence implementation).

正所謂 垂拱而治 就是應用程式的主體,應該無為而治 讓這些設定模式 design patterns 各司其職!

Persistence Ignorance http://bit.ly/2vwwqK1

Domain objects shouldn't know about persistence concerns

Once you've defined an interface to encapsulate your persistence operations, you can write the code that works with this interface.

However, before you can run it, you need to write an implementation of the interface, and use this implementation from your code.

If you simply instantiate it, you're still gluing your code to that implementation. A better approach that results in a more modular design is to take in the interface as a parameter, as you'll learn in the next section.

總之就是讓程式更彈性化、不要被綁死了。

6:10:00 The Strategy Design Pattern

The Strategy design pattern allows an object to have some of the details of its behavior encapsulated in another type, which is then provided to it as a parameter.

This pattern is closely related to dependency injection, which refers to the technique of passing dependencies (or injecting them) into classes, usually through their constructor.

不要貼得那麼近!

Dependency Injection http://bit.ly/2vz6iPB

A means of achieving loose coupling.

6:15:00 One approach that will cause coupling problems is to simply instantiate an instance directly in the method:

IOrderRepository orderRepository = new ……();

This approach is inflexible, and violates the Open-Closed Principle, because the only way to change the persistence behavior in the future is to modify this code.

You would then pass in the implementation of this strategy as a parameter to the class (or, less commonly, as a property or method parameter).

6:20:30 This class now follows the Explicit Dependencies Principle, because it clearly states in its constructor what its needed collaborators are.

6:21:30 It also better follows SRP (discussed in the encapsulation lesson), because it is no longer responsible for choosing the specific implementations it will collaborate with.

單純化 單一責任制

6:25:00 That decision can be made elsewhere, perhaps in a class whose sole responsibility is constructing the collaborators that the program will use.



6:26:10 The Singleton Antipattern

For some types, having more than one instance of the type within an application could result in adverse effects.

6:29:00 要避免  tight coupling

6:34:00 多線程 多執行緒 multi-threaded applications



6:44:00 The Static Cling Antipattern



6:53:00  Look for places where you are tightly coupling some implementation logic within a higher-level method or program. See if you can apply some of the patterns you've learned in this lesson to separate low-level implementation details into their own classes.

不要 tightly coupling  而要  separate low-level implementation details into their own classes.

Note that in these simple console applications, if you use the Strategy pattern, it's perfectly acceptable for the Main method to instantiate specific implementation types to provide to those classes that require them.

}

7:02:00 Lesson 20 of 20 Troubleshooting http://bit.ly/2vwwF7N

{

7:09:00 how to define scopes and statements are collectively referred to as the language's syntax.

7:30:10 圓滿了!南無阿彌陀佛

}

}


留言

熱門文章