搜档网
当前位置:搜档网 › Design Guidelines(ReactiveCocoa)

Design Guidelines(ReactiveCocoa)

Design Guidelines(ReactiveCocoa)
Design Guidelines(ReactiveCocoa)

# Design Guidelines

This document contains guidelines for projects that want to make use of

ReactiveCocoa. The content here is heavily inspired by the [Rx Design

Guidelines](https://www.sodocs.net/doc/ec1898776.html,/b/rxteam/archive/2010/10/28/rx-design-guidelines.aspx).

This document assumes basic familiarity

with the features of ReactiveCocoa. The [Framework Overview][] is a better

resource for getting up to speed on the main types and concepts provided by RAC.

**[The `Event` contract]事件的约定**

1. [`Next`s provide values or indicate the occurrence of events]next为事件的发生提供数值或者提示1. [Errors behave like exceptions and propagate immediately]Errors的行为类似于exceptions,会马上传递

1. [Completion indicates success]completion表示成功

1. [Interruption cancels outstanding work and usually propagates immediately] interruption会取消未完成的工作,通常会马上传递

1. [Events are serial]事件是连续的

1. [Events cannot be sent recursively]事件不能递归

1. [Events are sent synchronously by default]事件默认是异步发送的

**[The `Signal` contract]信号的约定**

1. [Signals start work when instantiated]信号一旦实例化后马上工作

1. [Observing a signal does not have side effects]观察信号不会有其他影响

1. [All observers of a signal see the same events in the same order]所有信号观察者对于同一个事件是同一个次序的

1. [A signal is retained until the underlying observer is released]信号对象会被保留直到其观察者被释放了

1. [Terminating events dispose of signal resources]信号源的部署会终止事件

**[The `SignalProducer` contract]信号产生的约定**

1. [Signal producers start work on demand by creating signals]需要产生信号的时候信号发生器才开始工作

1. [Each produced signal may send different events at different times]每个产生的信号可以在不同的时间发送不同的事件

1. [Signal operators can be lifted to apply to signal producers]信号的操作者能够被提升到信号产生者

1. [Disposing of a produced signal will interrupt it]部署一个发生的信号会中断他

**[Best practices](#best-practices)**

1. [Process only as many values as needed]只产生需要的值

1. [Observe events on a known scheduler]在一个已知的序列表中观察事件

1. [Switch schedulers in as few places as possible]尽量少的切换序列表

1. [Capture side effects within signal producers]捕获信号发生器的副作用

1. [Share the side effects of a signal producer by sharing one produced signal]通过共享一个信号来共享他的副作用

1. [Prefer managing lifetime with operators over explicit disposal]最好管理操作者在明确的部署中的生命周期

**[Implementing new operators](#implementing-new-operators)**

1. [Prefer writing operators that apply to both signals and producers]最好写出同时操作信号和发生器的操作者

1. [Compose existing operators when possible]尽可能的整理已经存在的操作者

1. [Forward error and interruption events as soon as possible]尽快的跳转到error和中断事件

1. [Switch over `Event` values]交换事件的值

1. [Avoid introducing concurrency]避免引入同时行

1. [Avoid blocking in operators]避免在操作者中使用block

## The `Event` contract

[Events][]are fundamental to ReactiveCocoa. [Signals][]and[signal producers][] both send events, and may be collectively called “event streams.”

Event streams must conform to the following grammar:

```

Next* (Interrupted | Error | Completed)?

```

This states that an event stream consists of:

1. Any number of `Next` events

1. Optionally followed by one terminating event, which is any of `Interrupted`, `Error`, or

`Completed`

After a terminating event, no other events will be received.

#### `Next`s provide values or indicate the occurrence of events

`Next` events contain a payload known as the “value.” Only `Next` events are

said to have a value. Since an event stream can contain any number of `Next`s,

there are few restrictions on what those values can mean or be used for, except

that they must be of the same type.

As an example, the value might represent an element from a collection, or

a progress update about some long-running operation. The value of a `Next` event

might even represent nothing at all—for exampl e, it’s common to use a value type

of `()` to indicate that something happened, without being more specific about

what that something was.

Most of the event stream [operators][] act upon `Next` events, as they represent the “meaningful data” of a signal or producer.

#### Errors behave like exceptions and propagate immediately

`Error` events indicate that something went wrong, and contain a concrete error

that indicates what happened. Errors are fatal, and propagate as quickly as

possible to the consumer for handling.

Errors also behave like exceptions, in that they “skip” operators, terminating

them along the way. In other words, most [operators][] immediately stop doing work

when an error is received, and then propagate the error onward. This even

applies to time-shifted operators, like [`delay`][delay]—which, despite its name, will forward any errors immediately.

Consequently, errors should only be used to represent “abnormal” termination. If

it is important to let operators (or consumers) finish their work, a `Next`

event describing the result might be more appropriate.

If an event stream can _never_ error out, it should be parameterized with the

special [`NoError`][NoError] type, which statically guarantees that an error

event cannot be sent upon the stream.

#### Completion indicates success

An event stream sends `Completed` when the operation has completed successfully,

or to indicate that the stream has terminated normally.

Many operators manipulate the `Completed` event to shorten or extend the

lifetime of an event stream.

For example, [`take`][take] will complete after the specified number of values have

been received, thereby terminating the stream early. On the other hand, most

operators that accept multiple signals or producers will wait until _all_ of

them have completed before forwarding a `Completed` event, since a successful outcome will usually depend on all the inputs.

#### Interruption cancels outstanding work and usually propagates immediately

An `Interrupted` event is sent when an event stream should cancel processing. Interruption is somewhere between [success](#completion-indicates-success)

and [failure](#errors-behave-like-exceptions-and-propagate-immediately)—the

operation was not successful, because it did not get to finish, but it didn’t

necessarily “fail” either.

Most [operators][] will propagate interruption immediately, but there are some exceptions. For example, the [flattening operators][flatten] will ignore

`Interrupted` events that occur on the _inner_ producers, since the cancellation

of an inner operation should not necessarily cancel the larger unit of work.

RAC will automatically send an `Interrupted` event upon [disposal][Disposables], but it can also be sent manually if necessary. Additionally, [custom

operators](#implementing-new-operators) must make sure to forward interruption

events to the observer.

#### Events are serial

RAC guarantees that all events upon a stream will arrive serially. In other

words, it’s impossible for the observer of a signal or producer to receive

multiple `Event`s concurrently, even if the events are sent on multiple threads simultaneously.

This simplifies [operator][Operators] implementations and [observers][].

#### Events cannot be sent recursively

Just like RAC guarantees that [events will not be received

concurrently](#events-are-serial), it also guarantees that they won’t be

received recursively. As a consequence, [operators][] and [observers][] _do not_ need to

be reentrant.

If an event is sent upon a signal from a thread that is _already processing_

a previous event from that signal, deadlock will result. This is because

recursive signals are usually programmer error, and the determinacy of

a deadlock is preferable to nondeterministic race conditions.

When a recursive signal is explicitly desired, the recursive event should be

time-shifted, with an operator like [`delay`][delay], to ensure that it isn’t sent from

an already-running event handler.

#### Events are sent synchronously by default

RAC does not implicitly introduce concurrency or asynchrony. [Operators][] that

accept a [scheduler][Schedulers] may, but they must be explicitly invoked by the consumer of the framework.

A “vanilla” signal or producer will send all of its events synchronously by

default, meaning that the [observer][Observers] will be synchronously invoked for each event as it is sent, and that the underlying work will not resume until the event

handler finishes.

This is similar to how `NSNotificationCenter` or `UIControl` events are

distributed.

## The `Signal` contract

A [signal][Signals] is an “always on” stream that obeys [the `Event`

contract](#the-event-contract).

`Signal` is a reference type, because each signal has identity—in other words, each

signal has its own lifetime, and may eventually terminate. Once terminated,

a signal cannot be restarted.

#### Signals start work when instantiated

[`Signal.init`][Signal.init] immediately executes the generator closure that is passed to it.

This means that side effects may occur even before the initializer returns.

It is also possible to send [events][] before the initializer returns. However,

since it is impossible for any [observers][] to be attached at this point, any

events sent this way cannot be received.

#### Observing a signal does not have side effects

The work associated with a `Signal` does not start or stop when [observers][] are

added or removed, so the [`observe`][observe] method (or the cancellation thereof) never has side effects.

A signal’s side effects can only be stopped through [a terminating

event](#signals-are-retained-until-a-terminating-event-occurs).

#### All observers of a signal see the same events in the same order

Because [observation does not have side

effects](#observing-a-signal-does-not-have-side-effects), a `Signal` never

customizes events for different [observers][]. When an event is sent upon a signal,

it will be [synchronously](#events-are-sent-synchronously-by-default)

distributed to all observers that are attached at that time, much like

how `NSNotificationCenter` sends notifications.

In other words, there are not different event “timelines” per observer. All

observers effectively see the same stream of events.

There is one exception to this rule: adding an observer to a signal _after_ it

has already terminated will result in exactly one

[`Interrupted`](#interruption-cancels-outstanding-work-and-usually-propagates-immediately) event sent to that specific observer.

#### A signal is retained until the underlying observer is released

Even if the caller does not maintain a reference to the `Signal`:

- A signal created with [`Signal.init`][Signal.init] is kept alive until the generator closure releases the [observer][Observers] argument.

- A signal created with [`Signal.pipe`][Signal.pipe] is kept alive until the returned observer is released.

This ensures that signals associated with long-running work do not deallocate prematurely.

Note that it is possible to release a signal before a terminating [event][Events] has been sent upon it. This should usually be avoided, as it can result in resource

leaks, but is sometimes useful to disable termination.

#### Terminating events dispose of signal resources

When a terminating [event][Events] is sent along a `Signal`, all [observers][] will be released, and any resources being used to generate events should be disposed of.

The easiest way to ensure proper resource cleanup is to return a [disposable][Disposables] from the generator closure, which will be disposed of when termination occurs.

The disposable should be responsible for releasing memory, closing file handles, canceling network requests, or anything else that may have been associated with

the work being performed.

## The `SignalProducer` contract

A [signal producer][Signal Producers] is like a “recipe” for creating

[signals][]. Signal producers do not do anything by themselves—[work begins only

when a signal is produced](#signal-producers-start-work-on-demand-by-creating-signals). Since a signal producer is just a declaration of _how_ to create signals, it is

a value type, and has no memory management to speak of.

#### Signal producers start work on demand by creating signals

The [`start`][start] and [`startWithSignal`][startWithSignal] methods each

produce a `Signal` (implicitly and explicitly, respectively). After

instantiating the signal, the closure that was passed to

[`SignalProducer.init`][SignalProducer.init] will be executed, to start the flow

of [events][] after any observers have been attached.

Although the producer itself is not _really_ responsible for the execution of

work, it’s common to speak of “starting” and “canceling” a producer. These terms

refer to producing a `Signal` that will start work, and [disposing of that

signal](#disposing-of-a-produced-signal-will-interrupt-it) to stop work.

A producer can be started any number of times (including zero), and the work associated with it will execute exactly that many times as well.

#### Each produced signal may send different events at different times

Because signal producers [start work on

demand](#signal-producers-start-work-on-demand-by-creating-signals), there may

be different [observers][] associated with each execution, and those observers

may see completely different [event][Events] timelines.

In other words, events are generated from scratch for each time the producer is started, and can be completely different (or in a completely different order)

from other times the producer is started.

Nonetheless, each execution of a signal producer will follow [the `Event`

contract](#the-event-contract).

#### Signal operators can be lifted to apply to signal producers

Due to the relationship between signals and signal producers, it is possible to automatically promote any [operators][] over one or more `Signal`s to apply to

the same number of `SignalProducer`s instead, using the [`lift`][lift] method.

`lift` will apply the behavior of the specified operator to each `Signal` that

is [created when the signal produced is

started](#signal-producers-start-work-on-demand-by-creating-signals).

#### Disposing of a produced signal will interrupt it

When a producer is started using the [`start`][start] or

[`startWithSignal`][startWithSignal] methods, a [`Disposable`][Disposables] is automatically created and passed back.

Disposing of this object will

[interrupt](#interruption-cancels-outstanding-work-and-usually-propagates-immediately) the produced `Signal`, thereby canceling outstanding work and sending an

`Interrupted` [event][Events] to all [observers][], and will also dispose of

everything added to the [`CompositeDisposable`][CompositeDisposable] in [SignalProducer.init].

Note that disposing of one produced `Signal` will not affect other signals created

by the same `SignalProducer`.

## Best practices

The following recommendations are intended to help keep RAC-based code predictable, understandable, and performant.

They are, however, only guidelines. Use best judgement when determining whether

to apply the recommendations here to a given piece of code.

#### Process only as many values as needed

Keeping an event stream alive longer than necessary can waste CPU and memory, as unnecessary work is performed for results that will never be used.

If only a certain number of values or certain number of time is required from

a [signal][Signals] or [producer][Signal Producers], operators like

[`take`][take] or [`takeUntil`][takeUntil] can be used to

automatically complete the stream once a certain condition is fulfilled.

The benefit is exponential, too, as this will terminate dependent operators

sooner, potentially saving a significant amount of work.

#### Observe events on a known scheduler

When receiving a [signal][Signals] or [producer][Signal Producers] from unknown code, it can be difficult to know which thread [events][] will arrive upon. Although events are [guaranteed to be serial](#events-are-serial), sometimes stronger guarantees are needed, like when performing UI updates (which must occur on the main thread).

Whenever such a guarantee is important, the [`observeOn`][observeOn] [operator][Operators] should be used to force events to be received upon

a specific [scheduler][Schedulers].

#### Switch schedulers in as few places as possible

Notwithstanding the [above](#observe-events-on-a-known-scheduler), [events][] should only be delivered to a specific [scheduler][Schedulers] when absolutely necessary. Switching schedulers can introduce unnecessary delays and cause an increase in CPU load.

Generally, [`observeOn`][observeOn] should only be used right before observing

the [signal][Signals], starting the [producer][Signal Producers], or binding to

a [property][Properties]. This ensures that events arrive on the expected

scheduler, without introducing multiple thread hops before their arrival.

#### Capture side effects within signal producers

Because [signal producers start work on

demand](#signal-producers-start-work-on-demand-by-creating-signals), any functions or methods that return a [signal producer][Signal Producers] should

make sure that side effects are captured _within_ the producer itself, instead

of being part of the function or method call.

For example, a function like this:

```swift

func search(text: String) ->SignalProducer

```

… should _not_ immediately start a search.

Instead, the returned producer should execute the search once for every time

that it is started. This also means that if the producer is never started,

a search will never have to be performed either.

#### Share the side effects of a signal producer by sharing one produced signal

If multiple [observers][] are interested in the results of a [signal

producer][Signal Producers], calling [`start`][start] once for each observer

means that the work associated with the producer will [execute that many

times](#signal-producers-start-work-on-demand-by-creating-signals) and [may not

generate the same results](#each-produced-signal-may-send-different-events-at-different-times). If:

1. the observers need to receive the exact same results

1. the observers know about each other, or

1. the code starting the producer knows about each observer

… it may be more appropriate to start the producer _just once_, and share the

results of that one [signal][Signals] to all observers, by attaching them within

the closure passed to the [`startWithSignal`][startWithSignal] method.

#### Prefer managing lifetime with operators over explicit disposal

Although the [disposable][Disposables] returned from [`start`][start] makes

canceling a [signal producer][Signal Producers] really easy, explicit use of

disposables can quickly lead to a rat's nest of resource management and cleanup

code.

There are almost always higher-level [operators][] that can be used instead of manual disposal:

* [`take`][take] can be used to automatically terminate a stream once a certain

number of values have been received.

* [`takeUntil`][takeUntil] can be used to automatically terminate

a [signal][Signals] or producer when an event occurs (for example, when

a “Cancel” button is pressed in the UI).

* [Properties][] and the `<~` operator can be used to “bind” the result of

a signal or producer, until termination or until the property is deallocated.

This can replace a manual observation that sets a value somewhere.

## Implementing new operators

RAC provides a long list of built-in [operators][] that should cover most use

cases; however, RAC is not a closed system. It's entirely valid to implement

additional operators for specialized uses, or for consideration in ReactiveCocoa

itself.

Implementing a new operator requires a careful attention to detail and a focus

on simplicity, to avoid introducing bugs into the calling code.

These guidelines cover some of the common pitfalls and help preserve the

expected API contracts. It may also help to look at the implementations of

existing `Signal` and `SignalProducer` operators for reference points.

#### Prefer writing operators that apply to both signals and producers

Since any [signal operator can apply to signal

producers](#signal-operators-can-be-lifted-to-apply-to-signal-producers),

writing custom operators in terms of [`Signal`][Signals] means that

[`SignalProducer`][Signal Producers] will get it “for free.”

Even if the caller only needs to apply the new operator to signal producers at

first, this generality can save time and effort in the future.

Of course, some capabilities _require_ producers (for example, any retrying or repeating), so it may not always be possible to write a signal-based version

instead.

#### Compose existing operators when possible

Considerable thought has been put into the operators provided by RAC, and they

have been validated through automated tests and through their real world use in

other projects. An operator that has been written from scratch may not be as

robust, or might not handle a special case that the built-in operators are aware

of.

To minimize duplication and possible bugs, use the provided operators as much as possible in a custom operator implementation. Generally, there should be very

little code written from scratch.

#### Forward error and interruption events as soon as possible

Unless an operator is specifically built to handle

[errors](#errors-behave-like-exceptions-and-propagate-immediately) and [interruption](#interruption-cancels-outstanding-work-and-usually-propagates-immedaitely) in a custom way, it should propagate those events to the observer as soon as

possible, to ensure that their semantics are honored.

#### Switch over `Event` values

Instead of using [`start(error:completed:interrupted:next:)`][start] or

[`observe(error:completed:interrupted:next:)`][observe], create your own

[observer][Observers] to process raw [`Event`][Events] values, and use

a `switch` statement to determine the event type.

For example:

```swift

producer.start(SinkOf { event in

switch event {

case let .Next(value):

println("Next event: \(value)")

case let .Error(error):

println("Error event: \(error)")

case .Completed:

println("Completed event")

case .Interrupted:

println("Interrupted event")

}

})

```

Since the compiler will generate a warning if the `switch` is missing any case,

this prevents mistakes in a custom operator’s event handling.

#### Avoid introducing concurrency

Concurrency is an extremely common source of bugs in programming. To minimize the potential for deadlocks and race conditions, operators should not

concurrently perform their work.

Callers always have the ability to [observe events on a specific

scheduler](#observe-events-on-a-known-scheduler), and RAC offers built-in ways to parallelize work, so custom operators don’t need t o be concerned with it.

#### Avoid blocking in operators

Signal or producer operators should return a new signal or producer (respectively) as quickly as possible. Any work that the operator needs to

perform should be part of the event handling logic, _not_ part of the operator invocation itself.

This guideline can be safely ignored when the purpose of an operator is to synchronously retrieve one or more values from a stream, like `single()` or

`wait()`.

[CompositeDisposable]: ../ReactiveCocoa/Swift/Disposable.swift [Disposables]: FrameworkOverview.md#disposables

[Events]: FrameworkOverview.md#events

[Framework Overview]: FrameworkOverview.md

[NoError]: ../ReactiveCocoa/Swift/Errors.swift

[Observers]: FrameworkOverview.md#observers

[Operators]: BasicOperators.md

[Properties]: FrameworkOverview.md#properties

[Schedulers]: FrameworkOverview.md#schedulers

[Signal Producers]: FrameworkOverview.md#signal-producers

[Signal.init]: ../ReactiveCocoa/Swift/Signal.swift

[Signal.pipe]: ../ReactiveCocoa/Swift/Signal.swift

[SignalProducer.init]: ../ReactiveCocoa/Swift/SignalProducer.swift

[Signals]: FrameworkOverview.md#signals

[delay]: ../ReactiveCocoa/Swift/Signal.swift

[flatten]: BasicOperators.md#flattening-producers

[lift]: ../ReactiveCocoa/Swift/SignalProducer.swift

[observe]: ../ReactiveCocoa/Swift/Signal.swift

[observeOn]: ../ReactiveCocoa/Swift/Signal.swift

[start]: ../ReactiveCocoa/Swift/SignalProducer.swift

[startWithSignal]: ../ReactiveCocoa/Swift/SignalProducer.swift

[take]: ../ReactiveCocoa/Swift/Signal.swift

[takeUntil]: ../ReactiveCocoa/Swift/Signal.swift

面相中的十大凶相都有这些,你知道吗,看完该注意了

面相中的十大凶相都有这些,你知道吗,看完该注意了 谓的面相‘五官’,指的就是‘耳、眉、眼、鼻、口’等五种人体器官。面相就是一个人所具有的独特气质,而成为形或色表现于面上,给人的一种感受。接下来为大家详细介绍面相算命图解大全。面相可分为三庭看,人的眉以上是上庭,人的眉至鼻头是中庭,人的鼻头以下就为下庭。面部三庭要均匀。即额头、眉眼鼻、嘴与下巴的比例要均匀,整个面部显得大方磊落。若是额形生得略高阔饱满,则代表少年运佳,但额不能太高,过高会克夫,太低则少年运差,当然没法早嫁。在面部五官之后,再细分便是十二宫。这十二个宫位囊括了面部所有的特性和吉凶。第一宫:命宫,又为愿望之宫。麻衣曰:其居两眉间,山根之上,为印堂。第二宫:财帛宫,位于土宿,包括天仓、地库、金甲、井灶。主察财运。第三宫:兄弟宫,又称交友宫。麻衣曰:位居两眉。主交友运。第四宫:田宅宫,田宅宫,位于两眼,及上眼睑。主家业运第五宫:男女宫,又称子女宫。麻衣曰:位于两眼之下,又称为泪堂。看子嗣运。第六宫:奴仆宫,麻衣说它位居地阁,重接水星。看管理运。第七宫:妻妾宫,也可以称为夫妻宫,就在眼尾。第八宫:疾厄宫,一说是山根位,一说是年寿位,建议以鼻梁统看。第九宫:迁移宫,迁移者,位居眉角。古相士,以迁移宫的位置看人阴阳宅状况。第十宫:官禄宫,

官禄者,为居中正,上合离宫。反应人的禄命官运。第十一宫:福德宫,福德者,位居天仓,牵连地阁。看福禄之运。第十二宫:父母宫,便是额头的日月角。主看父母的福祸疾厄。看面相,形体外貌、精神气质、举止情态皆可一视而察,情人、恋人、夫妻、同事、朋友之间、感情总会有变化的、是相互信任、倾慕也可以从面相看出来。额头眉毛之间只有一道纵纹。这种面相在相学中被称为天柱纹。有此面相的人个性都很顽强。是属于做事不达目的绝不会放弃,对利益也是分得很清楚。一般来讲他们是不做对自己无利的事情。这样的人不但严以律己。同时对别人的要求也非常严格。但还有就是是这种面相的人有一个特征,那就好是这道纵纹平时是不会出现。当他的身心俱疲的时候,这道皱纹才会出现。鼻子的上部这些部位若是出现了数条横纹的人。有此面相特征者对事物都会表现出十足的热情。甚至可以说是充满激情。不仅是做事情又积极又主动。待人处事也是持着一颗平常心。此外,如果是说笑时出现这种皱纹的人。一般性格都是较为温和。缺点就是比较好管别人的事情。也常常为此惹祸上身。 1、男人的眉毛中间稀疏杂乱、毛形逆生,是为乱性之相, 情绪十分不稳定,伴有较重的暴力倾向。-2、双眉过低而压眼,是为心性阴沉扭曲而走极端。-3、女子眉过粗浓,不仅一生婚姻难成,且有妨夫。-4、印堂过窄小,难容两指的人,一生运势不顺且多灾厄。-5、女子双颧露骨而突起,对夫运

14种鼻型图解

26种面型算命图解 侧面观察 1、凸面型 上停位居前额,代表十五至三十岁、父母缘分、思想智慧等事。从侧面观看,这种面型的额头是向后倾斜,表示思想敏捷,下巴向后退缩,不是行动迅速。 但一个人思想、行动都迅速,则其人是一个容易冲动的人 2、凹面型 这种面型的人额头与下巴皆凸出,形成中央鼻子部位凹入 这种人思想、行动都慢;但有忍耐力,不会轻易冲动,给人感觉城府很深,不轻易向他人吐露心声。 3、直面型 直面形是前额与下巴皆没有凸出或退缩,这种面型的人思想与行动都不会急躁或太慢,做任何事都会按部就班,从容面对。 4、额凸下巴退缩 额凸代表思想慢,下巴退缩则代表行动快。 这种面相的人思想慢而行动快,其行动往往未经深思熟虑,所以常有错误的抉择。 5、额斜下巴凸

额斜是思想迅速,下巴凸出是行动缓慢,这种人碰到任何问题都会立即得到思想是回应,但不会马上行动,而会慢慢地行动,大部分人都是这种下巴。 正面观察 正面观察面型的方法较侧面多,有西洋骨相学的三分法,中国的五分法、十分法 其实三分法与五分有许多相同之处,三分法是以人类的思想、行动、物欲享受划分种类,而十分法只是把三分发再细致分划为十种。 三分法 1、思想型 思想型的人其特点是上额广阔而高,下巴尖而小,形成一个倒三角形。 这种形格的人身材一般都属细小、腰部狭窄、手一般略长、面色带白、头发幼而密。 「思想型」这正是推动他们走向成功之路的因素;所以很多科学家、研究家在未成功之前常常会给人行为疯狂、不切实际之感觉。 这种形格的人适宜做科学研究、教育、建筑师、设计师或数学家、分析家等工作。 2、运动型

运动型的人特点就是颧骨高耸,鼻形长而鼻梁有节,腮骨显露,前额一般较低而额上有横纹、面色带黑、头发粗而多、身材高大强壮。其性格特点是忍耐力强,有冒险精神,有责任心,敢作敢为,刻苦耐劳。 这种面型的人最适合从事劳动工作,如工程师、冒险家、探险家、军人、警察或运动员等 3、享受型 享受型的人其特点是颐部园肥,前额较窄小,形成一个正三角形或圆形的面。鼻形较小,鼻头园而有肉,头发幼而疏,面色略微带红,手脚较短,脸部特别肥大,肉多骨少。 这种人处事圆滑,交际手腕强。这种人最适合经商 以上三种形质,只是基本形而已。因为每一个人同样会兼有思想型、运动型及享受型的特征,只是多寡而已,但最好是三种形质发展平衡,这样可工作不忘娱乐,娱乐不忘工作。 如果思想型过重的话,这种人每天只是充满幻想,不肯面对现实,容易引发神经衰落及头痛病等病症,如果再加上整个脸型搭配失宜,如眉粗,眼无神,鼻形短,这样的话,实际谋生能力多有问题。 如果运动型过重的话,则其人精力充沛,行事冲动,喜欢用武力解决问题。如果再加上形质配合不佳,如鼻形不端正,额骨凸露或低,眼神流露等,则其人大多从事低下的劳动工作,只能温饱而已,老来

相关主题